Importing rustc-1.48.0
Bug: 173721343
Change-Id: Ie8184d9a685086ca8a77266d6c608843f40dc9e1
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index a5ddf76..a3fbed2 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -177,6 +177,7 @@
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
+ #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub const fn dangling(&self) -> NonNull<u8> {
// SAFETY: align is guaranteed to be non-zero
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index ad4f8bf..6d09b4f 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -13,17 +13,17 @@
use crate::fmt;
use crate::ptr::{self, NonNull};
-/// The `AllocErr` error indicates an allocation failure
+/// The `AllocError` error indicates an allocation failure
/// that may be due to resource exhaustion or to
/// something wrong when combining the given input arguments with this
/// allocator.
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct AllocErr;
+pub struct AllocError;
// (we need this for downstream impl of trait Error)
#[unstable(feature = "allocator_api", issue = "32838")]
-impl fmt::Display for AllocErr {
+impl fmt::Display for AllocError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("memory allocation failed")
}
@@ -109,7 +109,7 @@
/// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
///
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
- fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr>;
+ fn alloc(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>;
/// Behaves like `alloc`, but also ensures that the returned memory is zero-initialized.
///
@@ -126,7 +126,7 @@
/// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
///
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
- fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+ fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
let ptr = self.alloc(layout)?;
// SAFETY: `alloc` returns a valid memory block
unsafe { ptr.as_non_null_ptr().as_ptr().write_bytes(0, ptr.len()) }
@@ -142,14 +142,13 @@
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
- unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
+ unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout);
/// Attempts to extend the memory block.
///
/// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
- /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
- /// alignment and a size given by `new_size`. To accomplish this, the allocator may extend the
- /// allocation referenced by `ptr` to fit the new layout.
+ /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
+ /// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout.
///
/// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
/// transferred to this allocator. The memory may or may not have been freed, and should be
@@ -163,11 +162,9 @@
///
/// # Safety
///
- /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
- /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
- /// * `new_size` must be greater than or equal to `layout.size()`, and
- /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
- /// (i.e., the rounded value must be less than or equal to `usize::MAX`).
+ /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
+ /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
+ /// * `new_layout.size()` must be greater than or equal to `old_layout.size()`.
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
@@ -186,30 +183,26 @@
///
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
unsafe fn grow(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
- let size = layout.size();
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
debug_assert!(
- new_size >= size,
- "`new_size` must be greater than or equal to `layout.size()`"
+ new_layout.size() >= old_layout.size(),
+ "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
);
- // SAFETY: the caller must ensure that the `new_size` does not overflow.
- // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
- let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
let new_ptr = self.alloc(new_layout)?;
- // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
- // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
- // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
- // `copy_nonoverlapping` is safe.
- // The safety contract for `dealloc` must be upheld by the caller.
+ // SAFETY: because `new_layout.size()` must be greater than or equal to
+ // `old_layout.size()`, both the old and new memory allocation are valid for reads and
+ // writes for `old_layout.size()` bytes. Also, because the old allocation wasn't yet
+ // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
+ // safe. The safety contract for `dealloc` must be upheld by the caller.
unsafe {
- ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), size);
- self.dealloc(ptr, layout);
+ ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_layout.size());
+ self.dealloc(ptr, old_layout);
}
Ok(new_ptr)
@@ -220,21 +213,19 @@
///
/// The memory block will contain the following contents after a successful call to
/// `grow_zeroed`:
- /// * Bytes `0..layout.size()` are preserved from the original allocation.
- /// * Bytes `layout.size()..old_size` will either be preserved or zeroed, depending on the
- /// allocator implementation. `old_size` refers to the size of the memory block prior to
- /// the `grow_zeroed` call, which may be larger than the size that was originally requested
- /// when it was allocated.
+ /// * Bytes `0..old_layout.size()` are preserved from the original allocation.
+ /// * Bytes `old_layout.size()..old_size` will either be preserved or zeroed, depending on
+ /// the allocator implementation. `old_size` refers to the size of the memory block prior
+ /// to the `grow_zeroed` call, which may be larger than the size that was originally
+ /// requested when it was allocated.
/// * Bytes `old_size..new_size` are zeroed. `new_size` refers to the size of the memory
- /// block returned by the `grow` call.
+ /// block returned by the `grow_zeroed` call.
///
/// # Safety
///
- /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
- /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
- /// * `new_size` must be greater than or equal to `layout.size()`, and
- /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
- /// (i.e., the rounded value must be less than or equal to `usize::MAX`).
+ /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
+ /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
+ /// * `new_layout.size()` must be greater than or equal to `old_layout.size()`.
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
@@ -253,30 +244,26 @@
///
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
unsafe fn grow_zeroed(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
- let size = layout.size();
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
debug_assert!(
- new_size >= size,
- "`new_size` must be greater than or equal to `layout.size()`"
+ new_layout.size() >= old_layout.size(),
+ "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
);
- // SAFETY: the caller must ensure that the `new_size` does not overflow.
- // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
- let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
let new_ptr = self.alloc_zeroed(new_layout)?;
- // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
- // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
- // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
- // `copy_nonoverlapping` is safe.
- // The safety contract for `dealloc` must be upheld by the caller.
+ // SAFETY: because `new_layout.size()` must be greater than or equal to
+ // `old_layout.size()`, both the old and new memory allocation are valid for reads and
+ // writes for `old_layout.size()` bytes. Also, because the old allocation wasn't yet
+ // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
+ // safe. The safety contract for `dealloc` must be upheld by the caller.
unsafe {
- ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), size);
- self.dealloc(ptr, layout);
+ ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_layout.size());
+ self.dealloc(ptr, old_layout);
}
Ok(new_ptr)
@@ -285,9 +272,8 @@
/// Attempts to shrink the memory block.
///
/// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
- /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
- /// alignment and a size given by `new_size`. To accomplish this, the allocator may shrink the
- /// allocation referenced by `ptr` to fit the new layout.
+ /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
+ /// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout.
///
/// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
/// transferred to this allocator. The memory may or may not have been freed, and should be
@@ -301,9 +287,9 @@
///
/// # Safety
///
- /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
- /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and
- /// * `new_size` must be smaller than or equal to `layout.size()`.
+ /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
+ /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
+ /// * `new_layout.size()` must be smaller than or equal to `old_layout.size()`.
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
@@ -322,30 +308,26 @@
///
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
unsafe fn shrink(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
- let size = layout.size();
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
debug_assert!(
- new_size <= size,
- "`new_size` must be smaller than or equal to `layout.size()`"
+ new_layout.size() <= old_layout.size(),
+ "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
);
- // SAFETY: the caller must ensure that the `new_size` does not overflow.
- // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
- let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
let new_ptr = self.alloc(new_layout)?;
- // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new
- // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the
- // old allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
- // `copy_nonoverlapping` is safe.
- // The safety contract for `dealloc` must be upheld by the caller.
+ // SAFETY: because `new_layout.size()` must be lower than or equal to
+ // `old_layout.size()`, both the old and new memory allocation are valid for reads and
+ // writes for `new_layout.size()` bytes. Also, because the old allocation wasn't yet
+ // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
+ // safe. The safety contract for `dealloc` must be upheld by the caller.
unsafe {
- ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), size);
- self.dealloc(ptr, layout);
+ ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), new_layout.size());
+ self.dealloc(ptr, old_layout);
}
Ok(new_ptr)
@@ -355,62 +337,62 @@
///
/// The returned adaptor also implements `AllocRef` and will simply borrow this.
#[inline(always)]
- fn by_ref(&mut self) -> &mut Self {
+ fn by_ref(&self) -> &Self {
self
}
}
#[unstable(feature = "allocator_api", issue = "32838")]
-unsafe impl<A> AllocRef for &mut A
+unsafe impl<A> AllocRef for &A
where
A: AllocRef + ?Sized,
{
#[inline]
- fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+ fn alloc(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
(**self).alloc(layout)
}
#[inline]
- fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+ fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
(**self).alloc_zeroed(layout)
}
#[inline]
- unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+ unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout) {
// SAFETY: the safety contract must be upheld by the caller
unsafe { (**self).dealloc(ptr, layout) }
}
#[inline]
unsafe fn grow(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
- unsafe { (**self).grow(ptr, layout, new_size) }
+ unsafe { (**self).grow(ptr, old_layout, new_layout) }
}
#[inline]
unsafe fn grow_zeroed(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
- unsafe { (**self).grow_zeroed(ptr, layout, new_size) }
+ unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) }
}
#[inline]
unsafe fn shrink(
- &mut self,
+ &self,
ptr: NonNull<u8>,
- layout: Layout,
- new_size: usize,
- ) -> Result<NonNull<[u8]>, AllocErr> {
+ old_layout: Layout,
+ new_layout: Layout,
+ ) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
- unsafe { (**self).shrink(ptr, layout, new_size) }
+ unsafe { (**self).shrink(ptr, old_layout, new_layout) }
}
}
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 919070a..cafb002 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -73,7 +73,7 @@
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked(self.alive.clone());
- MaybeUninit::slice_get_ref(slice)
+ MaybeUninit::slice_assume_init_ref(slice)
}
}
@@ -82,7 +82,7 @@
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked_mut(self.alive.clone());
- MaybeUninit::slice_get_mut(slice)
+ MaybeUninit::slice_assume_init_mut(slice)
}
}
}
@@ -103,7 +103,7 @@
// dead now (i.e. do not touch). As `idx` was the start of the
// alive-zone, the alive zone is now `data[alive]` again, restoring
// all invariants.
- unsafe { self.data.get_unchecked(idx).read() }
+ unsafe { self.data.get_unchecked(idx).assume_init_read() }
})
}
@@ -136,7 +136,7 @@
// dead now (i.e. do not touch). As `idx` was the end of the
// alive-zone, the alive zone is now `data[alive]` again, restoring
// all invariants.
- unsafe { self.data.get_unchecked(idx).read() }
+ unsafe { self.data.get_unchecked(idx).assume_init_read() }
})
}
}
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 88795d8..966272c 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -19,6 +19,20 @@
#[unstable(feature = "array_value_iter", issue = "65798")]
pub use iter::IntoIter;
+/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
+#[unstable(feature = "array_from_ref", issue = "77101")]
+pub fn from_ref<T>(s: &T) -> &[T; 1] {
+ // SAFETY: Converting `&T` to `&[T; 1]` is sound.
+ unsafe { &*(s as *const T).cast::<[T; 1]>() }
+}
+
+/// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
+#[unstable(feature = "array_from_ref", issue = "77101")]
+pub fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
+ // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
+ unsafe { &mut *(s as *mut T).cast::<[T; 1]>() }
+}
+
/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
@@ -362,7 +376,6 @@
array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
-#[cfg(not(bootstrap))]
#[lang = "array"]
impl<T, const N: usize> [T; N] {
/// Returns an array of the same size as `self`, with function `f` applied to each element
@@ -411,7 +424,7 @@
}
let mut dst = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<U, N> =
- Guard { dst: MaybeUninit::first_ptr_mut(&mut dst), initialized: 0 };
+ Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 };
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
dst.write(f(src));
guard.initialized += 1;
@@ -423,4 +436,17 @@
// and we just need to cast it to the correct type.
unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
}
+
+ /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
+ #[unstable(feature = "array_methods", issue = "76118")]
+ pub fn as_slice(&self) -> &[T] {
+ self
+ }
+
+ /// Returns a mutable slice containing the entire array. Equivalent to
+ /// `&mut s[..]`.
+ #[unstable(feature = "array_methods", issue = "76118")]
+ pub fn as_mut_slice(&mut self) -> &mut [T] {
+ self
+ }
}
diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs
index e78dfd1..a8a25f9 100644
--- a/library/core/src/ascii.rs
+++ b/library/core/src/ascii.rs
@@ -6,8 +6,6 @@
//!
//! The [`escape_default`] function provides an iterator over the bytes of an
//! escaped version of the character given.
-//!
-//! [`escape_default`]: fn.escape_default.html
#![stable(feature = "core_ascii", since = "1.26.0")]
@@ -20,8 +18,6 @@
///
/// This `struct` is created by the [`escape_default`] function. See its
/// documentation for more.
-///
-/// [`escape_default`]: fn.escape_default.html
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct EscapeDefault {
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index cbbfcb4..15ec13c 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -496,10 +496,7 @@
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
- // SAFETY: This can cause data races if called from a separate thread,
- // but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees
- // unique access.
- unsafe { &mut *self.value.get() }
+ self.value.get_mut()
}
/// Returns a `&Cell<T>` from a `&mut T`
@@ -700,6 +697,7 @@
/// ```
#[inline]
#[stable(feature = "refcell_replace", since = "1.24.0")]
+ #[track_caller]
pub fn replace(&self, t: T) -> T {
mem::replace(&mut *self.borrow_mut(), t)
}
@@ -722,6 +720,7 @@
/// ```
#[inline]
#[stable(feature = "refcell_replace_swap", since = "1.35.0")]
+ #[track_caller]
pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
let mut_borrow = &mut *self.borrow_mut();
let replacement = f(mut_borrow);
@@ -945,8 +944,7 @@
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
- // SAFETY: `&mut` guarantees unique access.
- unsafe { &mut *self.value.get() }
+ self.value.get_mut()
}
/// Undo the effect of leaked guards on the borrow state of the `RefCell`.
@@ -1056,6 +1054,7 @@
///
/// Panics if the value is currently mutably borrowed.
#[inline]
+ #[track_caller]
fn clone(&self) -> RefCell<T> {
RefCell::new(self.borrow().clone())
}
@@ -1543,8 +1542,11 @@
/// allow internal mutability, such as `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their
/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell<T>`.
///
-/// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to
-/// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly.
+/// The `UnsafeCell` API itself is technically very simple: [`.get()`] gives you a raw pointer
+/// `*mut T` to its contents. It is up to _you_ as the abstraction designer to use that raw pointer
+/// correctly.
+///
+/// [`.get()`]: `UnsafeCell::get`
///
/// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious:
///
@@ -1571,21 +1573,70 @@
/// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T`
/// co-exist with it. A `&mut T` must always be unique.
///
-/// Note that while mutating or mutably aliasing the contents of an `&UnsafeCell<T>` is
-/// ok (provided you enforce the invariants some other way), it is still undefined behavior
-/// to have multiple `&mut UnsafeCell<T>` aliases.
+/// Note that whilst mutating the contents of an `&UnsafeCell<T>` (even while other
+/// `&UnsafeCell<T>` references alias the cell) is
+/// ok (provided you enforce the above invariants some other way), it is still undefined behavior
+/// to have multiple `&mut UnsafeCell<T>` aliases. That is, `UnsafeCell` is a wrapper
+/// designed to have a special interaction with _shared_ accesses (_i.e._, through an
+/// `&UnsafeCell<_>` reference); there is no magic whatsoever when dealing with _exclusive_
+/// accesses (_e.g._, through an `&mut UnsafeCell<_>`): neither the cell nor the wrapped value
+/// may be aliased for the duration of that `&mut` borrow.
+/// This is showcased by the [`.get_mut()`] accessor, which is a non-`unsafe` getter that yields
+/// a `&mut T`.
+///
+/// [`.get_mut()`]: `UnsafeCell::get_mut`
///
/// # Examples
///
+/// Here is an example showcasing how to soundly mutate the contents of an `UnsafeCell<_>` despite
+/// there being multiple references aliasing the cell:
+///
/// ```
/// use std::cell::UnsafeCell;
///
-/// # #[allow(dead_code)]
-/// struct NotThreadSafe<T> {
-/// value: UnsafeCell<T>,
-/// }
+/// let x: UnsafeCell<i32> = 42.into();
+/// // Get multiple / concurrent / shared references to the same `x`.
+/// let (p1, p2): (&UnsafeCell<i32>, &UnsafeCell<i32>) = (&x, &x);
///
-/// unsafe impl<T> Sync for NotThreadSafe<T> {}
+/// unsafe {
+/// // SAFETY: within this scope there are no other references to `x`'s contents,
+/// // so ours is effectively unique.
+/// let p1_exclusive: &mut i32 = &mut *p1.get(); // -- borrow --+
+/// *p1_exclusive += 27; // |
+/// } // <---------- cannot go beyond this point -------------------+
+///
+/// unsafe {
+/// // SAFETY: within this scope nobody expects to have exclusive access to `x`'s contents,
+/// // so we can have multiple shared accesses concurrently.
+/// let p2_shared: &i32 = &*p2.get();
+/// assert_eq!(*p2_shared, 42 + 27);
+/// let p1_shared: &i32 = &*p1.get();
+/// assert_eq!(*p1_shared, *p2_shared);
+/// }
+/// ```
+///
+/// The following example showcases the fact that exclusive access to an `UnsafeCell<T>`
+/// implies exclusive access to its `T`:
+///
+/// ```rust
+/// #![feature(unsafe_cell_get_mut)]
+/// #![forbid(unsafe_code)] // with exclusive accesses,
+/// // `UnsafeCell` is a transparent no-op wrapper,
+/// // so no need for `unsafe` here.
+/// use std::cell::UnsafeCell;
+///
+/// let mut x: UnsafeCell<i32> = 42.into();
+///
+/// // Get a compile-time-checked unique reference to `x`.
+/// let p_unique: &mut UnsafeCell<i32> = &mut x;
+/// // With an exclusive reference, we can mutate the contents for free.
+/// *p_unique.get_mut() = 0;
+/// // Or, equivalently:
+/// x = UnsafeCell::new(0);
+///
+/// // When we own the value, we can extract the contents for free.
+/// let contents: i32 = x.into_inner();
+/// assert_eq!(contents, 0);
/// ```
#[lang = "unsafe_cell"]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1663,6 +1714,29 @@
self as *const UnsafeCell<T> as *const T as *mut T
}
+ /// Returns a mutable reference to the underlying data.
+ ///
+ /// This call borrows the `UnsafeCell` mutably (at compile-time) which
+ /// guarantees that we possess the only reference.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(unsafe_cell_get_mut)]
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let mut c = UnsafeCell::new(5);
+ /// *c.get_mut() += 1;
+ ///
+ /// assert_eq!(*c.get_mut(), 6);
+ /// ```
+ #[inline]
+ #[unstable(feature = "unsafe_cell_get_mut", issue = "76943")]
+ pub fn get_mut(&mut self) -> &mut T {
+ // SAFETY: (outer) `&mut` guarantees unique access.
+ unsafe { &mut *self.get() }
+ }
+
/// Gets a mutable pointer to the wrapped value.
/// The difference to [`get`] is that this function accepts a raw pointer,
/// which is useful to avoid the creation of temporary references.
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 7784ec6..a953a3a 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -7,11 +7,9 @@
//! contain owned boxes or implement [`Drop`]), so the compiler considers
//! them cheap and safe to copy. For other types copies must be made
//! explicitly, by convention implementing the [`Clone`] trait and calling
-//! the [`clone`][clone] method.
+//! the [`clone`] method.
//!
-//! [`Clone`]: trait.Clone.html
-//! [clone]: trait.Clone.html#tymethod.clone
-//! [`Drop`]: ../../std/ops/trait.Drop.html
+//! [`clone`]: Clone::clone
//!
//! Basic usage example:
//!
@@ -51,7 +49,9 @@
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
-/// implementation of [`clone`] calls [`clone`] on each field.
+/// implementation of [`Clone`] calls [`clone`] on each field.
+///
+/// [`clone`]: Clone::clone
///
/// For a generic struct, `#[derive]` implements `Clone` conditionally by adding bound `Clone` on
/// generic parameters.
@@ -74,9 +74,6 @@
/// An example is a generic struct holding a function pointer. In this case, the
/// implementation of `Clone` cannot be `derive`d, but can be implemented as:
///
-/// [`Copy`]: ../../std/marker/trait.Copy.html
-/// [`clone`]: trait.Clone.html#tymethod.clone
-///
/// ```
/// struct Generate<T>(fn() -> T);
///
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 3953c73..ee79a94 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -356,8 +356,9 @@
/// ```
#[inline]
#[must_use]
+ #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn reverse(self) -> Ordering {
+ pub const fn reverse(self) -> Ordering {
match self {
Less => Greater,
Equal => Equal,
@@ -394,8 +395,9 @@
/// ```
#[inline]
#[must_use]
+ #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
#[stable(feature = "ordering_chaining", since = "1.17.0")]
- pub fn then(self, other: Ordering) -> Ordering {
+ pub const fn then(self, other: Ordering) -> Ordering {
match self {
Equal => other,
_ => self,
@@ -724,19 +726,19 @@
/// }
///
/// impl PartialOrd for Person {
-/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
///
/// impl Ord for Person {
-/// fn cmp(&self, other: &Person) -> Ordering {
+/// fn cmp(&self, other: &Self) -> Ordering {
/// self.height.cmp(&other.height)
/// }
/// }
///
/// impl PartialEq for Person {
-/// fn eq(&self, other: &Person) -> bool {
+/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index fcd07be..2bfeb49 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -31,13 +31,6 @@
//! `into` themselves and `from` themselves
//!
//! See each trait for usage examples.
-//!
-//! [`Into`]: trait.Into.html
-//! [`From`]: trait.From.html
-//! [`TryFrom`]: trait.TryFrom.html
-//! [`TryInto`]: trait.TryInto.html
-//! [`AsRef`]: trait.AsRef.html
-//! [`AsMut`]: trait.AsMut.html
#![stable(feature = "rust1", since = "1.0.0")]
@@ -141,13 +134,11 @@
/// want to accept all references that can be converted to [`&str`] as an argument.
/// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument.
///
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
-/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
-/// [`Hash`]: ../../std/hash/trait.Hash.html
-/// [`Eq`]: ../../std/cmp/trait.Eq.html
-/// [`Ord`]: ../../std/cmp/trait.Ord.html
-/// [`&str`]: ../../std/primitive.str.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
+/// [`Borrow`]: crate::borrow::Borrow
+/// [`Eq`]: crate::cmp::Eq
+/// [`Ord`]: crate::cmp::Ord
/// [`String`]: ../../std/string/struct.String.html
///
/// ```
@@ -177,8 +168,8 @@
/// **Note: This trait must not fail**. If the conversion can fail, use a
/// dedicated method which returns an [`Option<T>`] or a [`Result<T, E>`].
///
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
///
/// # Generic Implementations
///
@@ -278,12 +269,9 @@
/// is_hello(s);
/// ```
///
-/// [`TryInto`]: trait.TryInto.html
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
/// [`String`]: ../../std/string/struct.String.html
-/// [`From`]: trait.From.html
-/// [`Into`]: trait.Into.html
/// [`Vec`]: ../../std/vec/struct.Vec.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Into<T>: Sized {
@@ -370,12 +358,10 @@
/// }
/// ```
///
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Option<T>`]: Option
+/// [`Result<T, E>`]: Result
/// [`String`]: ../../std/string/struct.String.html
-/// [`Into`]: trait.Into.html
-/// [`from`]: trait.From.html#tymethod.from
+/// [`from`]: From::from
/// [book]: ../../book/ch09-00-error-handling.html
#[rustc_diagnostic_item = "from_trait"]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -385,7 +371,7 @@
))]
pub trait From<T>: Sized {
/// Performs the conversion.
- #[cfg_attr(not(bootstrap), lang = "from")]
+ #[lang = "from"]
#[stable(feature = "rust1", since = "1.0.0")]
fn from(_: T) -> Self;
}
@@ -404,9 +390,6 @@
///
/// This suffers the same restrictions and reasoning as implementing
/// [`Into`], see there for details.
-///
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Into`]: trait.Into.html
#[stable(feature = "try_from", since = "1.34.0")]
pub trait TryInto<T>: Sized {
/// The type returned in the event of a conversion error.
@@ -485,11 +468,9 @@
/// assert!(try_successful_smaller_number.is_ok());
/// ```
///
-/// [`try_from`]: trait.TryFrom.html#tymethod.try_from
-/// [`TryInto`]: trait.TryInto.html
-/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
+/// [`i32::MAX`]: crate::i32::MAX
+/// [`try_from`]: TryFrom::try_from
/// [`!`]: ../../std/primitive.never.html
-/// [`Infallible`]: enum.Infallible.html
#[stable(feature = "try_from", since = "1.34.0")]
pub trait TryFrom<T>: Sized {
/// The type returned in the event of a conversion error.
@@ -676,7 +657,6 @@
///
/// … and eventually deprecate `Infallible`.
///
-///
/// However there is one case where `!` syntax can be used
/// before `!` is stabilized as a full-fledged type: in the position of a function’s return type.
/// Specifically, it is possible implementations for two different function pointer types:
@@ -692,10 +672,6 @@
/// the two `impl`s will start to overlap
/// and therefore will be disallowed by the language’s trait coherence rules.
///
-/// [`Ok`]: ../result/enum.Result.html#variant.Ok
-/// [`Result`]: ../result/enum.Result.html
-/// [`TryFrom`]: trait.TryFrom.html
-/// [`Into`]: trait.Into.html
/// [never]: ../../std/primitive.never.html
#[stable(feature = "convert_infallible", since = "1.34.0")]
#[derive(Copy)]
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index 52d8349..5908da4 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -14,25 +14,17 @@
where
T: flt2dec::DecodableFloat,
{
- // SAFETY: Possible undefined behavior, see FIXME(#53491)
- unsafe {
- let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
- let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
- // FIXME(#53491): This is calling `get_mut` on an uninitialized
- // `MaybeUninit` (here and elsewhere in this file). Revisit this once
- // we decided whether that is valid or not.
- // We can do this only because we are libstd and coupled to the compiler.
- // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
- let formatted = flt2dec::to_exact_fixed_str(
- flt2dec::strategy::grisu::format_exact,
- *num,
- sign,
- precision,
- buf.get_mut(),
- parts.get_mut(),
- );
- fmt.pad_formatted_parts(&formatted)
- }
+ let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
+ let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+ let formatted = flt2dec::to_exact_fixed_str(
+ flt2dec::strategy::grisu::format_exact,
+ *num,
+ sign,
+ precision,
+ &mut buf,
+ &mut parts,
+ );
+ fmt.pad_formatted_parts(&formatted)
}
// Don't inline this so callers that call both this and the above won't wind
@@ -47,22 +39,18 @@
where
T: flt2dec::DecodableFloat,
{
- // SAFETY: Possible undefined behavior, see FIXME(#53491)
- unsafe {
- // enough for f32 and f64
- let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
- let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
- // FIXME(#53491)
- let formatted = flt2dec::to_shortest_str(
- flt2dec::strategy::grisu::format_shortest,
- *num,
- sign,
- precision,
- buf.get_mut(),
- parts.get_mut(),
- );
- fmt.pad_formatted_parts(&formatted)
- }
+ // enough for f32 and f64
+ let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
+ let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+ let formatted = flt2dec::to_shortest_str(
+ flt2dec::strategy::grisu::format_shortest,
+ *num,
+ sign,
+ precision,
+ &mut buf,
+ &mut parts,
+ );
+ fmt.pad_formatted_parts(&formatted)
}
// Common code of floating point Debug and Display.
@@ -103,22 +91,18 @@
where
T: flt2dec::DecodableFloat,
{
- // SAFETY: Possible undefined behavior, see FIXME(#53491)
- unsafe {
- let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
- let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
- // FIXME(#53491)
- let formatted = flt2dec::to_exact_exp_str(
- flt2dec::strategy::grisu::format_exact,
- *num,
- sign,
- precision,
- upper,
- buf.get_mut(),
- parts.get_mut(),
- );
- fmt.pad_formatted_parts(&formatted)
- }
+ let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
+ let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+ let formatted = flt2dec::to_exact_exp_str(
+ flt2dec::strategy::grisu::format_exact,
+ *num,
+ sign,
+ precision,
+ upper,
+ &mut buf,
+ &mut parts,
+ );
+ fmt.pad_formatted_parts(&formatted)
}
// Don't inline this so callers that call both this and the above won't wind
@@ -133,23 +117,19 @@
where
T: flt2dec::DecodableFloat,
{
- // SAFETY: Possible undefined behavior, see FIXME(#53491)
- unsafe {
- // enough for f32 and f64
- let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
- let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
- // FIXME(#53491)
- let formatted = flt2dec::to_shortest_exp_str(
- flt2dec::strategy::grisu::format_shortest,
- *num,
- sign,
- (0, 0),
- upper,
- buf.get_mut(),
- parts.get_mut(),
- );
- fmt.pad_formatted_parts(&formatted)
- }
+ // enough for f32 and f64
+ let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
+ let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+ let formatted = flt2dec::to_shortest_exp_str(
+ flt2dec::strategy::grisu::format_shortest,
+ *num,
+ sign,
+ (0, 0),
+ upper,
+ &mut buf,
+ &mut parts,
+ );
+ fmt.pad_formatted_parts(&formatted)
}
// Common code of floating point LowerExp and UpperExp.
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 52f73c0..c1038ce 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -168,8 +168,6 @@
/// This method should generally not be invoked manually, but rather through
/// the [`write!`] macro itself.
///
- /// [`write!`]: ../../std/macro.write.html
- ///
/// # Examples
///
/// ```
@@ -2088,7 +2086,7 @@
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
if f.width.is_none() {
- f.width = Some(((mem::size_of::<usize>() * 8) / 4) + 2);
+ f.width = Some((usize::BITS / 4) as usize + 2);
}
}
f.flags |= 1 << (FlagV1::Alternate as u32);
@@ -2240,5 +2238,6 @@
}
}
-// If you expected tests to be here, look instead at the ui/ifmt.rs test,
+// If you expected tests to be here, look instead at the core/tests/fmt.rs file,
// it's a lot easier than creating all of the rt::Piece structures here.
+// There are also tests in the alloc crate, for those that need allocations.
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 7d77e33..ae3d0dd 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -85,7 +85,10 @@
// SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
// valid UTF-8
let buf = unsafe {
- str::from_utf8_unchecked(slice::from_raw_parts(MaybeUninit::first_ptr(buf), buf.len()))
+ str::from_utf8_unchecked(slice::from_raw_parts(
+ MaybeUninit::slice_as_ptr(buf),
+ buf.len(),
+ ))
};
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
}
@@ -192,7 +195,7 @@
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
let mut curr = buf.len() as isize;
- let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
+ let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
// SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
@@ -322,7 +325,7 @@
// that `curr >= 0`.
let mut buf = [MaybeUninit::<u8>::uninit(); 40];
let mut curr = buf.len() as isize; //index for buf
- let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
+ let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
// decode 2 chars at a time
@@ -370,7 +373,7 @@
// stores 'e' (or 'E') and the up to 2-digit exponent
let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3];
- let exp_ptr = MaybeUninit::first_ptr_mut(&mut exp_buf);
+ let exp_ptr = MaybeUninit::slice_as_mut_ptr(&mut exp_buf);
// SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]`
// is contained within `exp_buf` since `len <= 3`.
let exp_slice = unsafe {
diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs
index 8169c14..e9a99dd 100644
--- a/library/core/src/future/future.rs
+++ b/library/core/src/future/future.rs
@@ -23,7 +23,7 @@
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
///
-/// [`Waker`]: ../task/struct.Waker.html
+/// [`Waker`]: crate::task::Waker
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
@@ -91,12 +91,10 @@
/// (memory corruption, incorrect use of `unsafe` functions, or the like),
/// regardless of the future's state.
///
- /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
- /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
- /// [`Context`]: ../task/struct.Context.html
- /// [`Waker`]: ../task/struct.Waker.html
- /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
- #[cfg_attr(not(bootstrap), lang = "poll")]
+ /// [`Poll::Ready(val)`]: Poll::Ready
+ /// [`Waker`]: crate::task::Waker
+ /// [`Waker::wake`]: crate::task::Waker::wake
+ #[lang = "poll"]
#[stable(feature = "futures_api", since = "1.36.0")]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs
index d44ef85..fa5655c 100644
--- a/library/core/src/future/mod.rs
+++ b/library/core/src/future/mod.rs
@@ -21,9 +21,9 @@
#[unstable(feature = "into_future", issue = "67644")]
pub use into_future::IntoFuture;
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub use pending::{pending, Pending};
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub use ready::{ready, Ready};
#[unstable(feature = "future_poll_fn", issue = "72302")]
@@ -53,9 +53,10 @@
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
// This is `const` to avoid extra errors after we recover from `const async fn`
-#[cfg_attr(not(bootstrap), lang = "from_generator")]
+#[lang = "from_generator"]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
+#[rustc_const_unstable(feature = "gen_future", issue = "50547")]
#[inline]
pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
where
@@ -71,7 +72,7 @@
impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
type Output = T::Return;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- // Safety: Safe because we're !Unpin + !Drop, and this is just a field projection.
+ // SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
// Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The
@@ -86,7 +87,7 @@
GenFuture(gen)
}
-#[cfg_attr(not(bootstrap), lang = "get_context")]
+#[lang = "get_context"]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[inline]
diff --git a/library/core/src/future/pending.rs b/library/core/src/future/pending.rs
index 74887b6..ab16263 100644
--- a/library/core/src/future/pending.rs
+++ b/library/core/src/future/pending.rs
@@ -1,3 +1,4 @@
+use crate::fmt::{self, Debug};
use crate::future::Future;
use crate::marker;
use crate::pin::Pin;
@@ -6,12 +7,9 @@
/// Creates a future which never resolves, representing a computation that never
/// finishes.
///
-/// This `struct` is created by the [`pending`] function. See its
+/// This `struct` is created by [`pending()`]. See its
/// documentation for more.
-///
-/// [`pending`]: fn.pending.html
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
-#[derive(Debug)]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Pending<T> {
_data: marker::PhantomData<T>,
@@ -23,7 +21,6 @@
/// # Examples
///
/// ```no_run
-/// #![feature(future_readiness_fns)]
/// use core::future;
///
/// # async fn run() {
@@ -32,12 +29,12 @@
/// unreachable!();
/// # }
/// ```
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn pending<T>() -> Pending<T> {
Pending { _data: marker::PhantomData }
}
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Pending<T> {
type Output = T;
@@ -46,10 +43,17 @@
}
}
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Pending<T> {}
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
+impl<T> Debug for Pending<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Pending").finish()
+ }
+}
+
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Clone for Pending<T> {
fn clone(&self) -> Self {
pending()
diff --git a/library/core/src/future/poll_fn.rs b/library/core/src/future/poll_fn.rs
index 9ab3bfc..f302cda 100644
--- a/library/core/src/future/poll_fn.rs
+++ b/library/core/src/future/poll_fn.rs
@@ -33,10 +33,8 @@
/// A Future that wraps a function returning `Poll`.
///
-/// This `struct` is created by the [`poll_fn`] function. See its
+/// This `struct` is created by [`poll_fn()`]. See its
/// documentation for more.
-///
-/// [`poll_fn`]: fn.poll_fn.html
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[unstable(feature = "future_poll_fn", issue = "72302")]
pub struct PollFn<F> {
diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs
index 31b39d7..e98f5c5 100644
--- a/library/core/src/future/ready.rs
+++ b/library/core/src/future/ready.rs
@@ -4,19 +4,17 @@
/// Creates a future that is immediately ready with a value.
///
-/// This `struct` is created by the [`ready`] function. See its
+/// This `struct` is created by [`ready()`]. See its
/// documentation for more.
-///
-/// [`ready`]: fn.ready.html
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>);
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Ready<T> {}
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Ready<T> {
type Output = T;
@@ -28,10 +26,13 @@
/// Creates a future that is immediately ready with a value.
///
+/// Futures created through this function are functionally similar to those
+/// created through `async {}`. The main difference is that futures created
+/// through this function are named and implement `Unpin`.
+///
/// # Examples
///
/// ```
-/// #![feature(future_readiness_fns)]
/// use core::future;
///
/// # async fn run() {
@@ -39,7 +40,7 @@
/// assert_eq!(a.await, 1);
/// # }
/// ```
-#[unstable(feature = "future_readiness_fns", issue = "70921")]
+#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn ready<T>(t: T) -> Ready<T> {
Ready(Some(t))
}
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 6abe19d..f53ba98 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -39,8 +39,6 @@
//! If you need more control over how a value is hashed, you need to implement
//! the [`Hash`] trait:
//!
-//! [`Hash`]: trait.Hash.html
-//!
//! ```rust
//! use std::collections::hash_map::DefaultHasher;
//! use std::hash::{Hash, Hasher};
@@ -149,11 +147,9 @@
/// Thankfully, you won't need to worry about upholding this property when
/// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
///
-/// [`Eq`]: ../../std/cmp/trait.Eq.html
-/// [`Hasher`]: trait.Hasher.html
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
-/// [`hash`]: #tymethod.hash
+/// [`hash`]: Hash::hash
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Hash {
/// Feeds this value into the given [`Hasher`].
@@ -168,8 +164,6 @@
/// 7920.hash(&mut hasher);
/// println!("Hash is {:x}!", hasher.finish());
/// ```
- ///
- /// [`Hasher`]: trait.Hasher.html
#[stable(feature = "rust1", since = "1.0.0")]
fn hash<H: Hasher>(&self, state: &mut H);
@@ -186,8 +180,6 @@
/// Hash::hash_slice(&numbers, &mut hasher);
/// println!("Hash is {:x}!", hasher.finish());
/// ```
- ///
- /// [`Hasher`]: trait.Hasher.html
#[stable(feature = "hash_slice", since = "1.3.0")]
fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
where
@@ -239,10 +231,9 @@
/// println!("Hash is {:x}!", hasher.finish());
/// ```
///
-/// [`Hash`]: trait.Hash.html
-/// [`finish`]: #tymethod.finish
-/// [`write`]: #tymethod.write
-/// [`write_u8`]: #method.write_u8
+/// [`finish`]: Hasher::finish
+/// [`write`]: Hasher::write
+/// [`write_u8`]: Hasher::write_u8
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Hasher {
/// Returns the hash value for the values written so far.
@@ -264,7 +255,7 @@
/// println!("Hash is {:x}!", hasher.finish());
/// ```
///
- /// [`write`]: #tymethod.write
+ /// [`write`]: Hasher::write
#[stable(feature = "rust1", since = "1.0.0")]
fn finish(&self) -> u64;
@@ -433,8 +424,7 @@
/// assert_eq!(hasher_1.finish(), hasher_2.finish());
/// ```
///
-/// [`build_hasher`]: #tymethod.build_hasher
-/// [`Hasher`]: trait.Hasher.html
+/// [`build_hasher`]: BuildHasher::build_hasher
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
#[stable(since = "1.7.0", feature = "build_hasher")]
pub trait BuildHasher {
@@ -456,8 +446,6 @@
/// let s = RandomState::new();
/// let new_s = s.build_hasher();
/// ```
- ///
- /// [`Hasher`]: trait.Hasher.html
#[stable(since = "1.7.0", feature = "build_hasher")]
fn build_hasher(&self) -> Self::Hasher;
}
@@ -470,7 +458,7 @@
/// defined.
///
/// Any `BuildHasherDefault` is [zero-sized]. It can be created with
-/// [`default`][method.Default]. When using `BuildHasherDefault` with [`HashMap`] or
+/// [`default`][method.default]. When using `BuildHasherDefault` with [`HashMap`] or
/// [`HashSet`], this doesn't need to be done, since they implement appropriate
/// [`Default`] instances themselves.
///
@@ -503,10 +491,7 @@
/// let hash_map = HashMap::<u32, u32, MyBuildHasher>::default();
/// ```
///
-/// [`BuildHasher`]: trait.BuildHasher.html
-/// [`Default`]: ../default/trait.Default.html
-/// [method.default]: #method.default
-/// [`Hasher`]: trait.Hasher.html
+/// [method.default]: BuildHasherDefault::default
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
/// [zero-sized]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 461b4c7..4eb47dd 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -101,17 +101,18 @@
/// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html
///
/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
-/// use `x` in any possible valid way that Rust code is allowed to without introducing undefined
+/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
/// certain optimizations are not desired, such as benchmarks.
///
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
-#[inline]
+#[cfg_attr(not(miri), inline)]
+#[cfg_attr(miri, inline(never))]
#[unstable(feature = "test", issue = "50297")]
-#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
-pub fn black_box<T>(dummy: T) -> T {
+#[cfg_attr(miri, allow(unused_mut))]
+pub fn black_box<T>(mut dummy: T) -> T {
// We need to "use" the argument in some way LLVM can't introspect, and on
// targets that support it we can typically leverage inline assembly to do
// this. LLVM's interpretation of inline assembly is that it's, well, a black
@@ -121,7 +122,8 @@
#[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
// SAFETY: the inline assembly is a no-op.
unsafe {
- llvm_asm!("" : : "r"(&dummy));
+ // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
+ llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
}
dummy
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index d0b12d6..426cdb1 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1,7 +1,7 @@
//! Compiler intrinsics.
//!
-//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
-//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
+//! The corresponding definitions are in `compiler/rustc_codegen_llvm/src/intrinsic.rs`.
+//! The corresponding const implementations are in `compiler/rustc_mir/src/interpret/intrinsics.rs`
//!
//! # Const intrinsics
//!
@@ -10,7 +10,7 @@
//!
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
//! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
-//! `librustc_mir/interpret/intrinsics.rs` and add a
+//! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
//!
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
@@ -733,6 +733,7 @@
/// own, or if it does not enable any significant optimizations.
///
/// This intrinsic does not have a stable counterpart.
+ #[rustc_const_unstable(feature = "const_assume", issue = "76972")]
pub fn assume(b: bool);
/// Hints to the compiler that branch condition is likely to be true.
@@ -831,7 +832,7 @@
/// Gets a reference to a static `Location` indicating where it was called.
///
/// Consider using [`crate::panic::Location::caller`] instead.
- #[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
+ #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
pub fn caller_location() -> &'static crate::panic::Location<'static>;
/// Moves a value out of scope without running drop glue.
@@ -904,7 +905,7 @@
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
///
/// let num = unsafe {
- /// std::mem::transmute::<[u8; 4], u32>(raw_bytes);
+ /// std::mem::transmute::<[u8; 4], u32>(raw_bytes)
/// };
///
/// // use `u32::from_ne_bytes` instead
@@ -1071,6 +1072,7 @@
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
// checks that prevent its use within `const fn`.
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "transmute")]
pub fn transmute<T, U>(e: T) -> U;
/// Returns `true` if the actual type given as `T` requires drop
@@ -1899,11 +1901,22 @@
/// ```
/// use std::ptr;
///
+/// /// # Safety
+/// ///
+/// /// * `ptr` must be correctly aligned for its type and non-zero.
+/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
+/// /// * Those elements must not be used after calling this function unless `T: Copy`.
/// # #[allow(dead_code)]
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
-/// dst.set_len(elts);
+///
+/// // SAFETY: Our precondition ensures the source is aligned and valid,
+/// // and `Vec::with_capacity` ensures that we have usable space to write them.
/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
+///
+/// // SAFETY: We created it with this much capacity earlier,
+/// // and the previous `copy` has initialized these elements.
+/// dst.set_len(elts);
/// dst
/// }
/// ```
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index 6700ef0..ac27ec1 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -4,11 +4,19 @@
/// An iterator that links two iterators together, in a chain.
///
-/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
-/// documentation for more.
+/// This `struct` is created by [`Iterator::chain`]. See its documentation
+/// for more.
///
-/// [`chain`]: trait.Iterator.html#method.chain
-/// [`Iterator`]: trait.Iterator.html
+/// # Examples
+///
+/// ```
+/// use std::iter::Chain;
+/// use std::slice::Iter;
+///
+/// let a1 = [1, 2, 3];
+/// let a2 = [4, 5, 6];
+/// let iter: Chain<Iter<_>, Iter<_>> = a1.iter().chain(a2.iter());
+/// ```
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 4202e52..ddb1aae 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -7,11 +7,8 @@
/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
-/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`flat_map`]: trait.Iterator.html#method.flat_map
-/// [`Iterator`]: trait.Iterator.html
+/// This `struct` is created by [`Iterator::flat_map`]. See its documentation
+/// for more.
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct FlatMap<I, U: IntoIterator, F> {
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs
index ee5fbe9..a78da36 100644
--- a/library/core/src/iter/adapters/fuse.rs
+++ b/library/core/src/iter/adapters/fuse.rs
@@ -1,5 +1,7 @@
+use super::InPlaceIterable;
use crate::intrinsics;
use crate::iter::adapters::zip::try_get_unchecked;
+use crate::iter::adapters::SourceIter;
use crate::iter::TrustedRandomAccess;
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
use crate::ops::Try;
@@ -7,11 +9,8 @@
/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
-/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`fuse`]: trait.Iterator.html#method.fuse
-/// [`Iterator`]: trait.Iterator.html
+/// This `struct` is created by [`Iterator::fuse`]. See its documentation
+/// for more.
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -121,7 +120,8 @@
Self: TrustedRandomAccess,
{
match self.iter {
- // SAFETY: the caller must uphold the contract for `Iterator::get_unchecked`.
+ // SAFETY: the caller must uphold the contract for
+ // `Iterator::__iterator_get_unchecked`.
Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
// SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
None => unsafe { intrinsics::unreachable() },
@@ -517,3 +517,24 @@
unchecked!(self).is_empty()
}
}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
+where
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ match self.iter {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
+ // SAFETY: the specialized iterator never sets `None`
+ None => unsafe { intrinsics::unreachable() },
+ }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index ce90607..a725fb0 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -1,10 +1,12 @@
use crate::cmp;
use crate::fmt;
use crate::intrinsics;
-use crate::ops::{Add, AddAssign, Try};
+use crate::ops::{Add, AddAssign, ControlFlow, Try};
-use super::{from_fn, LoopState};
-use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
+use super::from_fn;
+use super::{
+ DoubleEndedIterator, ExactSizeIterator, FusedIterator, InPlaceIterable, Iterator, TrustedLen,
+};
mod chain;
mod flatten;
@@ -16,9 +18,77 @@
pub use self::flatten::{FlatMap, Flatten};
pub use self::fuse::Fuse;
use self::zip::try_get_unchecked;
-pub(crate) use self::zip::TrustedRandomAccess;
+#[unstable(feature = "trusted_random_access", issue = "none")]
+pub use self::zip::TrustedRandomAccess;
pub use self::zip::Zip;
+/// This trait provides transitive access to source-stage in an interator-adapter pipeline
+/// under the conditions that
+/// * the iterator source `S` itself implements `SourceIter<Source = S>`
+/// * there is a delegating implementation of this trait for each adapter in the pipeline between
+/// the source and the pipeline consumer.
+///
+/// When the source is an owning iterator struct (commonly called `IntoIter`) then
+/// this can be useful for specializing [`FromIterator`] implementations or recovering the
+/// remaining elements after an iterator has been partially exhausted.
+///
+/// Note that implementations do not necessarily have to provide access to the inner-most
+/// source of a pipeline. A stateful intermediate adapter might eagerly evaluate a part
+/// of the pipeline and expose its internal storage as source.
+///
+/// The trait is unsafe because implementers must uphold additional safety properties.
+/// See [`as_inner`] for details.
+///
+/// # Examples
+///
+/// Retrieving a partially consumed source:
+///
+/// ```
+/// # #![feature(inplace_iteration)]
+/// # use std::iter::SourceIter;
+///
+/// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
+/// let _ = iter.next();
+/// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
+/// println!("n = {} elements remaining", remainder.len());
+/// ```
+///
+/// [`FromIterator`]: crate::iter::FromIterator
+/// [`as_inner`]: SourceIter::as_inner
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub unsafe trait SourceIter {
+ /// A source stage in an iterator pipeline.
+ type Source: Iterator;
+
+ /// Retrieve the source of an iterator pipeline.
+ ///
+ /// # Safety
+ ///
+ /// Implementations of must return the same mutable reference for their lifetime, unless
+ /// replaced by a caller.
+ /// Callers may only replace the reference when they stopped iteration and drop the
+ /// iterator pipeline after extracting the source.
+ ///
+ /// This means iterator adapters can rely on the source not changing during
+ /// iteration but they cannot rely on it in their Drop implementations.
+ ///
+ /// Implementing this method means adapters relinquish private-only access to their
+ /// source and can only rely on guarantees made based on method receiver types.
+ /// The lack of restricted access also requires that adapters must uphold the source's
+ /// public API even when they have access to its internals.
+ ///
+ /// Callers in turn must expect the source to be in any state that is consistent with
+ /// its public API since adapters sitting between it and the source have the same
+ /// access. In particular an adapter may have consumed more elements than strictly necessary.
+ ///
+ /// The overall goal of these requirements is to let the consumer of a pipeline use
+ /// * whatever remains in the source after iteration has stopped
+ /// * the memory that has become unused by advancing a consuming iterator
+ ///
+ /// [`next()`]: trait.Iterator.html#method.next
+ unsafe fn as_inner(&mut self) -> &mut Self::Source;
+}
+
/// A double-ended iterator with the direction inverted.
///
/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
@@ -55,6 +125,11 @@
}
#[inline]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ self.iter.advance_back_by(n)
+ }
+
+ #[inline]
fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
self.iter.nth_back(n)
}
@@ -95,6 +170,11 @@
}
#[inline]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ self.iter.advance_by(n)
+ }
+
+ #[inline]
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
self.iter.nth(n)
}
@@ -220,7 +300,7 @@
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
*unsafe { try_get_unchecked(&mut self.it, idx) }
}
}
@@ -355,7 +435,7 @@
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
unsafe { try_get_unchecked(&mut self.it, idx).clone() }
}
}
@@ -870,7 +950,7 @@
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
}
}
@@ -939,6 +1019,24 @@
}
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for Map<I, F>
+where
+ F: FnMut(I::Item) -> B,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for Map<I, F> where F: FnMut(I::Item) -> B {}
+
/// An iterator that filters the elements of `iter` with `predicate`.
///
/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its
@@ -1070,6 +1168,24 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
+
/// An iterator that uses `f` to both filter and map elements from `iter`.
///
/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
@@ -1164,10 +1280,10 @@
#[inline]
fn find<T, B>(
f: &mut impl FnMut(T) -> Option<B>,
- ) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
+ ) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
move |(), x| match f(x) {
- Some(x) => LoopState::Break(x),
- None => LoopState::Continue(()),
+ Some(x) => ControlFlow::Break(x),
+ None => ControlFlow::CONTINUE,
}
}
@@ -1196,6 +1312,27 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F>
+where
+ F: FnMut(I::Item) -> Option<B>,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where
+ F: FnMut(I::Item) -> Option<B>
+{
+}
+
/// An iterator that yields the current count and the element during iteration.
///
/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
@@ -1309,7 +1446,7 @@
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
(Add::add(self.count, idx), value)
}
@@ -1414,6 +1551,23 @@
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
+where
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}
+
/// An iterator with a `peek()` that returns an optional reference to the next
/// element.
///
@@ -1628,7 +1782,7 @@
self.peeked.get_or_insert_with(|| iter.next()).as_ref()
}
- /// Consume the next value of this iterator if a condition is true.
+ /// Consume and return the next value of this iterator if a condition is true.
///
/// If `func` returns `true` for the next value of this iterator, consume and return it.
/// Otherwise, return `None`.
@@ -1668,7 +1822,7 @@
}
}
- /// Consume the next item if it is equal to `expected`.
+ /// Consume and return the next item if it is equal to `expected`.
///
/// # Example
/// Consume a number if it's equal to 0.
@@ -1683,15 +1837,35 @@
/// assert_eq!(iter.next(), Some(1));
/// ```
#[unstable(feature = "peekable_next_if", issue = "72480")]
- pub fn next_if_eq<R>(&mut self, expected: &R) -> Option<I::Item>
+ pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
where
- R: ?Sized,
- I::Item: PartialEq<R>,
+ T: ?Sized,
+ I::Item: PartialEq<T>,
{
self.next_if(|next| next == expected)
}
}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Peekable<I>
+where
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}
+
/// An iterator that rejects elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
@@ -1793,6 +1967,27 @@
{
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where
+ F: FnMut(&I::Item) -> bool
+{
+}
+
/// An iterator that only accepts elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
@@ -1864,13 +2059,13 @@
flag: &'a mut bool,
p: &'a mut impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| {
if p(&x) {
- LoopState::from_try(fold(acc, x))
+ ControlFlow::from_try(fold(acc, x))
} else {
*flag = true;
- LoopState::Break(Try::from_ok(acc))
+ ControlFlow::Break(Try::from_ok(acc))
}
}
}
@@ -1907,6 +2102,27 @@
{
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where
+ F: FnMut(&I::Item) -> bool
+{
+}
+
/// An iterator that only accepts elements while `predicate` returns `Some(_)`.
///
/// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its
@@ -1963,8 +2179,8 @@
{
let Self { iter, predicate } = self;
iter.try_fold(init, |acc, x| match predicate(x) {
- Some(item) => LoopState::from_try(fold(acc, item)),
- None => LoopState::Break(Try::from_ok(acc)),
+ Some(item) => ControlFlow::from_try(fold(acc, item)),
+ None => ControlFlow::Break(Try::from_ok(acc)),
})
.into_try()
}
@@ -1984,6 +2200,27 @@
}
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, P> SourceIter for MapWhile<I, P>
+where
+ P: FnMut(I::Item) -> Option<B>,
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> where
+ P: FnMut(I::Item) -> Option<B>
+{
+}
+
/// An iterator that skips over `n` elements of `iter`.
///
/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
@@ -2135,11 +2372,11 @@
fn check<T, Acc, R: Try<Ok = Acc>>(
mut n: usize,
mut fold: impl FnMut(Acc, T) -> R,
- ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> {
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
move |acc, x| {
n -= 1;
let r = fold(acc, x);
- if n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
+ if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}
@@ -2167,6 +2404,23 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Skip<I>
+where
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {}
+
/// An iterator that only iterates over the first `n` iterations of `iter`.
///
/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
@@ -2246,11 +2500,11 @@
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
n: &'a mut usize,
mut fold: impl FnMut(Acc, T) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| {
*n -= 1;
let r = fold(acc, x);
- if *n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
+ if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}
@@ -2277,6 +2531,23 @@
}
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
+where
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
+
#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I>
where
@@ -2414,10 +2685,10 @@
state: &'a mut St,
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
mut fold: impl FnMut(Acc, B) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
move |acc, x| match f(state, x) {
- None => LoopState::Break(Try::from_ok(acc)),
- Some(x) => LoopState::from_try(fold(acc, x)),
+ None => ControlFlow::Break(Try::from_ok(acc)),
+ Some(x) => ControlFlow::from_try(fold(acc, x)),
}
}
@@ -2441,6 +2712,27 @@
}
}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
+where
+ I: SourceIter<Source = S>,
+ F: FnMut(&mut St, I::Item) -> Option<B>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> where
+ F: FnMut(&mut St, I::Item) -> Option<B>
+{
+}
+
/// An iterator that calls a function with a reference to each element before
/// yielding it.
///
@@ -2587,6 +2879,24 @@
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+ I: SourceIter<Source = S>,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.iter) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}
+
/// An iterator adapter that produces output as long as the underlying
/// iterator produces `Result::Ok` values.
///
@@ -2638,10 +2948,10 @@
let error = &mut *self.error;
self.iter
.try_fold(init, |acc, x| match x {
- Ok(x) => LoopState::from_try(f(acc, x)),
+ Ok(x) => ControlFlow::from_try(f(acc, x)),
Err(e) => {
*error = Err(e);
- LoopState::Break(Try::from_ok(acc))
+ ControlFlow::Break(Try::from_ok(acc))
}
})
.into_try()
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs
index 581ac6e..7871298 100644
--- a/library/core/src/iter/adapters/zip.rs
+++ b/library/core/src/iter/adapters/zip.rs
@@ -1,15 +1,15 @@
use crate::cmp;
use crate::fmt::{self, Debug};
-use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
+use super::super::{
+ DoubleEndedIterator, ExactSizeIterator, FusedIterator, InPlaceIterable, Iterator, SourceIter,
+ TrustedLen,
+};
/// An iterator that iterates two other iterators simultaneously.
///
-/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`zip`]: trait.Iterator.html#method.zip
-/// [`Iterator`]: trait.Iterator.html
+/// This `struct` is created by [`Iterator::zip`]. See its documentation
+/// for more.
#[derive(Clone)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -63,8 +63,8 @@
where
Self: TrustedRandomAccess,
{
- // SAFETY: `ZipImpl::get_unchecked` has same safety requirements as
- // `Iterator::get_unchecked`.
+ // SAFETY: `ZipImpl::__iterator_get_unchecked` has same safety
+ // requirements as `Iterator::__iterator_get_unchecked`.
unsafe { ZipImpl::get_unchecked(self, idx) }
}
}
@@ -93,7 +93,7 @@
where
A: DoubleEndedIterator + ExactSizeIterator,
B: DoubleEndedIterator + ExactSizeIterator;
- // This has the same safety requirements as `Iterator::get_unchecked`
+ // This has the same safety requirements as `Iterator::__iterator_get_unchecked`
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
where
Self: Iterator + TrustedRandomAccess;
@@ -290,7 +290,7 @@
#[inline]
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }
}
}
@@ -331,6 +331,32 @@
{
}
+// Arbitrarily selects the left side of the zip iteration as extractable "source"
+// it would require negative trait bounds to be able to try both
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S, A, B> SourceIter for Zip<A, B>
+where
+ A: SourceIter<Source = S>,
+ B: Iterator,
+ S: Iterator,
+{
+ type Source = S;
+
+ #[inline]
+ unsafe fn as_inner(&mut self) -> &mut S {
+ // SAFETY: unsafe function forwarding to unsafe function with the same requirements
+ unsafe { SourceIter::as_inner(&mut self.a) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+// Limited to Item: Copy since interaction between Zip's use of TrustedRandomAccess
+// and Drop implementation of the source is unclear.
+//
+// An additional method returning the number of times the source has been logically advanced
+// (without calling next()) would be needed to properly drop the remainder of the source.
+unsafe impl<A: InPlaceIterable, B: Iterator> InPlaceIterable for Zip<A, B> where A::Item: Copy {}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Debug, B: Debug> Debug for Zip<A, B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -364,8 +390,8 @@
///
/// `size` may not be overridden.
///
-/// `<Self as Iterator>::get_unchecked` must be safe to call provided the
-/// following conditions are met.
+/// `<Self as Iterator>::__iterator_get_unchecked` must be safe to call
+/// provided the following conditions are met.
///
/// 1. `0 <= idx` and `idx < self.size()`.
/// 2. If `self: !Clone`, then `get_unchecked` is never called with the same
@@ -377,7 +403,7 @@
/// * `std::clone::Clone::clone`
/// * `std::iter::Iterator::size_hint()`
/// * `std::iter::Iterator::next_back()`
-/// * `std::iter::Iterator::get_unchecked()`
+/// * `std::iter::Iterator::__iterator_get_unchecked()`
/// * `std::iter::TrustedRandomAccess::size()`
///
/// Further, given that these conditions are met, it must guarantee that:
@@ -402,7 +428,7 @@
fn may_have_side_effect() -> bool;
}
-/// Like `Iterator::get_unchecked`, but doesn't require the compiler to
+/// Like `Iterator::__iterator_get_unchecked`, but doesn't require the compiler to
/// know that `U: TrustedRandomAccess`.
///
/// ## Safety
@@ -414,13 +440,13 @@
I: Iterator,
{
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
unsafe { it.try_get_unchecked(idx) }
}
unsafe trait SpecTrustedRandomAccess: Iterator {
/// If `Self: TrustedRandomAccess`, it must be safe to call a
- /// `Iterator::get_unchecked(self, index)`.
+ /// `Iterator::__iterator_get_unchecked(self, index)`.
unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item;
}
@@ -433,7 +459,7 @@
unsafe impl<I: Iterator + TrustedRandomAccess> SpecTrustedRandomAccess for I {
unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for
- // `Iterator::get_unchecked`.
+ // `Iterator::__iterator_get_unchecked`.
unsafe { self.__iterator_get_unchecked(index) }
}
}
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 9b528cd..59f333e 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -54,8 +54,7 @@
//! below for more details.
//!
//! [`Some(Item)`]: Some
-//! [`Iterator`]: trait.Iterator.html
-//! [`next`]: trait.Iterator.html#tymethod.next
+//! [`next`]: Iterator::next
//! [`TryIter`]: ../../std/sync/mpsc/struct.TryIter.html
//!
//! # The three forms of iteration
@@ -136,7 +135,7 @@
//! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling
//! `next`.
//!
-//! # for Loops and IntoIterator
+//! # `for` loops and `IntoIterator`
//!
//! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
//! example of `for`:
@@ -159,8 +158,7 @@
//! Let's take a look at that `for` loop again, and what the compiler converts
//! it into:
//!
-//! [`IntoIterator`]: trait.IntoIterator.html
-//! [`into_iter`]: trait.IntoIterator.html#tymethod.into_iter
+//! [`into_iter`]: IntoIterator::into_iter
//!
//! ```
//! let values = vec![1, 2, 3, 4, 5];
@@ -222,9 +220,9 @@
//! across versions of Rust, so you should avoid relying on the exact values
//! returned by an iterator which panicked.
//!
-//! [`map`]: trait.Iterator.html#method.map
-//! [`take`]: trait.Iterator.html#method.take
-//! [`filter`]: trait.Iterator.html#method.filter
+//! [`map`]: Iterator::map
+//! [`take`]: Iterator::take
+//! [`filter`]: Iterator::filter
//!
//! # Laziness
//!
@@ -261,13 +259,13 @@
//! }
//! ```
//!
-//! [`map`]: trait.Iterator.html#method.map
-//! [`for_each`]: trait.Iterator.html#method.for_each
+//! [`map`]: Iterator::map
+//! [`for_each`]: Iterator::for_each
//!
//! Another common way to evaluate an iterator is to use the [`collect`]
//! method to produce a new collection.
//!
-//! [`collect`]: trait.Iterator.html#method.collect
+//! [`collect`]: Iterator::collect
//!
//! # Infinity
//!
@@ -305,13 +303,11 @@
//! println!("The smallest number one is {}.", least);
//! ```
//!
-//! [`take`]: trait.Iterator.html#method.take
-//! [`min`]: trait.Iterator.html#method.min
+//! [`take`]: Iterator::take
+//! [`min`]: Iterator::min
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::ops::Try;
-
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::Iterator;
@@ -346,16 +342,24 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{ExactSizeIterator, Product, Sum};
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub use self::traits::InPlaceIterable;
+
#[stable(feature = "iter_cloned", since = "1.1.0")]
pub use self::adapters::Cloned;
#[stable(feature = "iter_copied", since = "1.36.0")]
pub use self::adapters::Copied;
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::adapters::Flatten;
+
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::adapters::MapWhile;
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub use self::adapters::SourceIter;
#[stable(feature = "iterator_step_by", since = "1.28.0")]
pub use self::adapters::StepBy;
+#[unstable(feature = "trusted_random_access", issue = "none")]
+pub use self::adapters::TrustedRandomAccess;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::adapters::{Chain, Cycle, Enumerate, Filter, FilterMap, Map, Rev, Zip};
#[stable(feature = "rust1", since = "1.0.0")]
@@ -363,63 +367,9 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::adapters::{Fuse, Inspect};
-pub(crate) use self::adapters::{process_results, TrustedRandomAccess};
+pub(crate) use self::adapters::process_results;
mod adapters;
mod range;
mod sources;
mod traits;
-
-/// Used to make try_fold closures more like normal loops
-#[derive(PartialEq)]
-enum LoopState<C, B> {
- Continue(C),
- Break(B),
-}
-
-impl<C, B> Try for LoopState<C, B> {
- type Ok = C;
- type Error = B;
- #[inline]
- fn into_result(self) -> Result<Self::Ok, Self::Error> {
- match self {
- LoopState::Continue(y) => Ok(y),
- LoopState::Break(x) => Err(x),
- }
- }
- #[inline]
- fn from_error(v: Self::Error) -> Self {
- LoopState::Break(v)
- }
- #[inline]
- fn from_ok(v: Self::Ok) -> Self {
- LoopState::Continue(v)
- }
-}
-
-impl<C, B> LoopState<C, B> {
- #[inline]
- fn break_value(self) -> Option<B> {
- match self {
- LoopState::Continue(..) => None,
- LoopState::Break(x) => Some(x),
- }
- }
-}
-
-impl<R: Try> LoopState<R::Ok, R> {
- #[inline]
- fn from_try(r: R) -> Self {
- match Try::into_result(r) {
- Ok(v) => LoopState::Continue(v),
- Err(v) => LoopState::Break(Try::from_error(v)),
- }
- }
- #[inline]
- fn into_try(self) -> R {
- match self {
- LoopState::Continue(v) => Try::from_ok(v),
- LoopState::Break(v) => v,
- }
- }
-}
diff --git a/library/core/src/iter/sources.rs b/library/core/src/iter/sources.rs
index d76fa89..97562cf 100644
--- a/library/core/src/iter/sources.rs
+++ b/library/core/src/iter/sources.rs
@@ -5,9 +5,7 @@
/// An iterator that repeats an element endlessly.
///
-/// This `struct` is created by the [`repeat`] function. See its documentation for more.
-///
-/// [`repeat`]: fn.repeat.html
+/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
@@ -47,15 +45,11 @@
/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
-/// [`take`], in order to make them finite.
-///
-/// [`take`]: trait.Iterator.html#method.take
+/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
-/// instead use the [`repeat_with`] function.
-///
-/// [`repeat_with`]: fn.repeat_with.html
+/// instead use the [`repeat_with()`] function.
///
/// # Examples
///
@@ -77,7 +71,7 @@
/// assert_eq!(Some(4), fours.next());
/// ```
///
-/// Going finite with [`take`]:
+/// Going finite with [`Iterator::take()`]:
///
/// ```
/// use std::iter;
@@ -102,10 +96,8 @@
/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
-/// This `struct` is created by the [`repeat_with`] function.
+/// This `struct` is created by the [`repeat_with()`] function.
/// See its documentation for more.
-///
-/// [`repeat_with`]: fn.repeat_with.html
#[derive(Copy, Clone, Debug)]
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub struct RepeatWith<F> {
@@ -139,20 +131,18 @@
/// The `repeat_with()` function calls the repeater over and over again.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
-/// [`take`], in order to make them finite.
+/// [`Iterator::take()`], in order to make them finite.
///
-/// [`take`]: trait.Iterator.html#method.take
-///
-/// If the element type of the iterator you need implements `Clone`, and
+/// If the element type of the iterator you need implements [`Clone`], and
/// it is OK to keep the source element in memory, you should instead use
-/// the [`repeat`] function.
+/// the [`repeat()`] function.
///
-/// [`repeat`]: fn.repeat.html
-///
-/// An iterator produced by `repeat_with()` is not a `DoubleEndedIterator`.
-/// If you need `repeat_with()` to return a `DoubleEndedIterator`,
+/// An iterator produced by `repeat_with()` is not a [`DoubleEndedIterator`].
+/// If you need `repeat_with()` to return a [`DoubleEndedIterator`],
/// please open a GitHub issue explaining your use case.
///
+/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator
+///
/// # Examples
///
/// Basic usage:
@@ -201,9 +191,7 @@
/// An iterator that yields nothing.
///
-/// This `struct` is created by the [`empty`] function. See its documentation for more.
-///
-/// [`empty`]: fn.empty.html
+/// This `struct` is created by the [`empty()`] function. See its documentation for more.
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);
@@ -292,9 +280,7 @@
/// An iterator that yields an element exactly once.
///
-/// This `struct` is created by the [`once`] function. See its documentation for more.
-///
-/// [`once`]: fn.once.html
+/// This `struct` is created by the [`once()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
pub struct Once<T> {
@@ -336,12 +322,12 @@
/// Creates an iterator that yields an element exactly once.
///
-/// This is commonly used to adapt a single value into a [`chain`] of other
+/// This is commonly used to adapt a single value into a [`chain()`] of other
/// kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
-/// [`chain`]: trait.Iterator.html#method.chain
+/// [`chain()`]: Iterator::chain
///
/// # Examples
///
@@ -393,10 +379,8 @@
/// An iterator that yields a single element of type `A` by
/// applying the provided closure `F: FnOnce() -> A`.
///
-/// This `struct` is created by the [`once_with`] function.
+/// This `struct` is created by the [`once_with()`] function.
/// See its documentation for more.
-///
-/// [`once_with`]: fn.once_with.html
#[derive(Clone, Debug)]
#[stable(feature = "iter_once_with", since = "1.43.0")]
pub struct OnceWith<F> {
@@ -442,15 +426,14 @@
/// Creates an iterator that lazily generates a value exactly once by invoking
/// the provided closure.
///
-/// This is commonly used to adapt a single value generator into a [`chain`] of
+/// This is commonly used to adapt a single value generator into a [`chain()`] of
/// other kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
-/// Unlike [`once`], this function will lazily generate the value on request.
+/// Unlike [`once()`], this function will lazily generate the value on request.
///
-/// [`once`]: fn.once.html
-/// [`chain`]: trait.Iterator.html#method.chain
+/// [`chain()`]: Iterator::chain
///
/// # Examples
///
@@ -505,17 +488,16 @@
///
/// This allows creating a custom iterator with any behavior
/// without using the more verbose syntax of creating a dedicated type
-/// and implementing the `Iterator` trait for it.
+/// and implementing the [`Iterator`] trait for it.
///
/// Note that the `FromFn` iterator doesn’t make assumptions about the behavior of the closure,
/// and therefore conservatively does not implement [`FusedIterator`],
-/// or override [`Iterator::size_hint`] from its default `(0, None)`.
-///
-/// [`FusedIterator`]: trait.FusedIterator.html
-/// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint
+/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
///
/// The closure can use captures and its environment to track state across iterations. Depending on
-/// how the iterator is used, this may require specifying the `move` keyword on the closure.
+/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
+///
+/// [`move`]: ../../std/keyword.move.html
///
/// # Examples
///
@@ -549,10 +531,10 @@
/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
///
-/// This `struct` is created by the [`iter::from_fn`] function.
+/// This `struct` is created by the [`iter::from_fn()`] function.
/// See its documentation for more.
///
-/// [`iter::from_fn`]: fn.from_fn.html
+/// [`iter::from_fn()`]: from_fn
#[derive(Clone)]
#[stable(feature = "iter_from_fn", since = "1.34.0")]
pub struct FromFn<F>(F);
@@ -601,10 +583,10 @@
/// An new iterator where each successive item is computed based on the preceding one.
///
-/// This `struct` is created by the [`successors`] function.
+/// This `struct` is created by the [`iter::successors()`] function.
/// See its documentation for more.
///
-/// [`successors`]: fn.successors.html
+/// [`iter::successors()`]: successors
#[derive(Clone)]
#[stable(feature = "iter_successors", since = "1.34.0")]
pub struct Successors<T, F> {
diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs
index 494c751..dc0d808 100644
--- a/library/core/src/iter/traits/accum.rs
+++ b/library/core/src/iter/traits/accum.rs
@@ -4,14 +4,13 @@
/// Trait to represent types that can be created by summing up an iterator.
///
-/// This trait is used to implement the [`sum`] method on iterators. Types which
-/// implement the trait can be generated by the [`sum`] method. Like
+/// This trait is used to implement the [`sum()`] method on iterators. Types which
+/// implement the trait can be generated by the [`sum()`] method. Like
/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::sum`].
+/// interacted with through [`Iterator::sum()`].
///
-/// [`sum`]: #tymethod.sum
-/// [`FromIterator`]: crate::iter::FromIterator
-/// [`Iterator::sum`]: crate::iter::Iterator::sum
+/// [`sum()`]: Sum::sum
+/// [`FromIterator`]: iter::FromIterator
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
pub trait Sum<A = Self>: Sized {
/// Method which takes an iterator and generates `Self` from the elements by
@@ -23,14 +22,13 @@
/// Trait to represent types that can be created by multiplying elements of an
/// iterator.
///
-/// This trait is used to implement the [`product`] method on iterators. Types
-/// which implement the trait can be generated by the [`product`] method. Like
+/// This trait is used to implement the [`product()`] method on iterators. Types
+/// which implement the trait can be generated by the [`product()`] method. Like
/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::product`].
+/// interacted with through [`Iterator::product()`].
///
-/// [`product`]: #tymethod.product
-/// [`FromIterator`]: crate::iter::FromIterator
-/// [`Iterator::product`]: crate::iter::Iterator::product
+/// [`product()`]: Product::product
+/// [`FromIterator`]: iter::FromIterator
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
pub trait Product<A = Self>: Sized {
/// Method which takes an iterator and generates `Self` from the elements by
@@ -120,9 +118,9 @@
where
T: Sum<U>,
{
- /// Takes each element in the `Iterator`: if it is an `Err`, no further
- /// elements are taken, and the `Err` is returned. Should no `Err` occur,
- /// the sum of all elements is returned.
+ /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
+ /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
+ /// occur, the sum of all elements is returned.
///
/// # Examples
///
@@ -150,9 +148,9 @@
where
T: Product<U>,
{
- /// Takes each element in the `Iterator`: if it is an `Err`, no further
- /// elements are taken, and the `Err` is returned. Should no `Err` occur,
- /// the product of all elements is returned.
+ /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
+ /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
+ /// occur, the product of all elements is returned.
fn product<I>(iter: I) -> Result<T, E>
where
I: Iterator<Item = Result<U, E>>,
@@ -166,9 +164,9 @@
where
T: Sum<U>,
{
- /// Takes each element in the `Iterator`: if it is a `None`, no further
- /// elements are taken, and the `None` is returned. Should no `None` occur,
- /// the sum of all elements is returned.
+ /// Takes each element in the [`Iterator`]: if it is a [`None`], no further
+ /// elements are taken, and the [`None`] is returned. Should no [`None`]
+ /// occur, the sum of all elements is returned.
///
/// # Examples
///
@@ -193,9 +191,9 @@
where
T: Product<U>,
{
- /// Takes each element in the `Iterator`: if it is a `None`, no further
- /// elements are taken, and the `None` is returned. Should no `None` occur,
- /// the product of all elements is returned.
+ /// Takes each element in the [`Iterator`]: if it is a [`None`], no further
+ /// elements are taken, and the [`None`] is returned. Should no [`None`]
+ /// occur, the product of all elements is returned.
fn product<I>(iter: I) -> Option<T>
where
I: Iterator<Item = Option<U>>,
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index 84c7787..41a503c 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -1,21 +1,15 @@
-/// Conversion from an `Iterator`.
+/// Conversion from an [`Iterator`].
///
/// By implementing `FromIterator` for a type, you define how it will be
/// created from an iterator. This is common for types which describe a
/// collection of some kind.
///
-/// `FromIterator`'s [`from_iter`] is rarely called explicitly, and is instead
-/// used through [`Iterator`]'s [`collect`] method. See [`collect`]'s
+/// [`FromIterator::from_iter()`] is rarely called explicitly, and is instead
+/// used through [`Iterator::collect()`] method. See [`Iterator::collect()`]'s
/// documentation for more examples.
///
-/// [`from_iter`]: #tymethod.from_iter
-/// [`Iterator`]: trait.Iterator.html
-/// [`collect`]: trait.Iterator.html#method.collect
-///
/// See also: [`IntoIterator`].
///
-/// [`IntoIterator`]: trait.IntoIterator.html
-///
/// # Examples
///
/// Basic usage:
@@ -30,7 +24,7 @@
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
///
-/// Using [`collect`] to implicitly use `FromIterator`:
+/// Using [`Iterator::collect()`] to implicitly use `FromIterator`:
///
/// ```
/// let five_fives = std::iter::repeat(5).take(5);
@@ -119,7 +113,7 @@
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
-/// Conversion into an `Iterator`.
+/// Conversion into an [`Iterator`].
///
/// By implementing `IntoIterator` for a type, you define how it will be
/// converted to an iterator. This is common for types which describe a
@@ -130,8 +124,6 @@
///
/// See also: [`FromIterator`].
///
-/// [`FromIterator`]: trait.FromIterator.html
-///
/// # Examples
///
/// Basic usage:
@@ -235,7 +227,7 @@
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
- #[cfg_attr(not(bootstrap), lang = "into_iter")]
+ #[lang = "into_iter"]
#[stable(feature = "rust1", since = "1.0.0")]
fn into_iter(self) -> Self::IntoIter;
}
@@ -326,7 +318,7 @@
/// As this is the only required method for this trait, the [trait-level] docs
/// contain more details.
///
- /// [trait-level]: trait.Extend.html
+ /// [trait-level]: Extend
///
/// # Examples
///
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index 851a1e4..2280799 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -1,5 +1,4 @@
-use crate::iter::LoopState;
-use crate::ops::Try;
+use crate::ops::{ControlFlow, Try};
/// An iterator able to yield elements from both ends.
///
@@ -11,11 +10,12 @@
/// and do not cross: iteration is over when they meet in the middle.
///
/// In a similar fashion to the [`Iterator`] protocol, once a
-/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again
-/// may or may not ever return `Some` again. `next()` and `next_back()` are
-/// interchangeable for this purpose.
+/// `DoubleEndedIterator` returns [`None`] from a [`next_back()`], calling it
+/// again may or may not ever return [`Some`] again. [`next()`] and
+/// [`next_back()`] are interchangeable for this purpose.
///
-/// [`Iterator`]: trait.Iterator.html
+/// [`next_back()`]: DoubleEndedIterator::next_back
+/// [`next()`]: Iterator::next
///
/// # Examples
///
@@ -43,7 +43,7 @@
///
/// The [trait-level] docs contain more details.
///
- /// [trait-level]: trait.DoubleEndedIterator.html
+ /// [trait-level]: DoubleEndedIterator
///
/// # Examples
///
@@ -67,7 +67,7 @@
/// # Remarks
///
/// The elements yielded by `DoubleEndedIterator`'s methods may differ from
- /// the ones yielded by `Iterator`'s methods:
+ /// the ones yielded by [`Iterator`]'s methods:
///
/// ```
/// let vec = vec![(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b')];
@@ -88,25 +88,63 @@
/// vec![(2, 'b'), (1, 'c')]
/// );
/// ```
- ///
#[stable(feature = "rust1", since = "1.0.0")]
fn next_back(&mut self) -> Option<Self::Item>;
+ /// Advances the iterator from the back by `n` elements.
+ ///
+ /// `advance_back_by` is the reverse version of [`advance_by`]. This method will
+ /// eagerly skip `n` elements starting from the back by calling [`next_back`] up
+ /// to `n` times until [`None`] is encountered.
+ ///
+ /// `advance_back_by(n)` will return [`Ok(())`] if the iterator successfully advances by
+ /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number of
+ /// elements the iterator is advanced by before running out of elements (i.e. the length
+ /// of the iterator). Note that `k` is always less than `n`.
+ ///
+ /// Calling `advance_back_by(0)` does not consume any elements and always returns [`Ok(())`].
+ ///
+ /// [`advance_by`]: Iterator::advance_by
+ /// [`next_back`]: DoubleEndedIterator::next_back
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(iter_advance_by)]
+ ///
+ /// let a = [3, 4, 5, 6];
+ /// let mut iter = a.iter();
+ ///
+ /// assert_eq!(iter.advance_back_by(2), Ok(()));
+ /// assert_eq!(iter.next_back(), Some(&4));
+ /// assert_eq!(iter.advance_back_by(0), Ok(()));
+ /// assert_eq!(iter.advance_back_by(100), Err(1)); // only `&3` was skipped
+ /// ```
+ #[inline]
+ #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ for i in 0..n {
+ self.next_back().ok_or(i)?;
+ }
+ Ok(())
+ }
+
/// Returns the `n`th element from the end of the iterator.
///
- /// This is essentially the reversed version of [`nth`]. Although like most indexing
- /// operations, the count starts from zero, so `nth_back(0)` returns the first value from
- /// the end, `nth_back(1)` the second, and so on.
+ /// This is essentially the reversed version of [`Iterator::nth()`].
+ /// Although like most indexing operations, the count starts from zero, so
+ /// `nth_back(0)` returns the first value from the end, `nth_back(1)` the
+ /// second, and so on.
///
/// Note that all elements between the end and the returned element will be
/// consumed, including the returned element. This also means that calling
/// `nth_back(0)` multiple times on the same iterator will return different
/// elements.
///
- /// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the
- /// iterator.
- ///
- /// [`nth`]: crate::iter::Iterator::nth
+ /// `nth_back()` will return [`None`] if `n` is greater than or equal to the
+ /// length of the iterator.
///
/// # Examples
///
@@ -136,20 +174,13 @@
/// ```
#[inline]
#[stable(feature = "iter_nth_back", since = "1.37.0")]
- fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
- for x in self.rev() {
- if n == 0 {
- return Some(x);
- }
- n -= 1;
- }
- None
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ self.advance_back_by(n).ok()?;
+ self.next_back()
}
- /// This is the reverse version of [`try_fold()`]: it takes elements
- /// starting from the back of the iterator.
- ///
- /// [`try_fold()`]: trait.Iterator.html#method.try_fold
+ /// This is the reverse version of [`Iterator::try_fold()`]: it takes
+ /// elements starting from the back of the iterator.
///
/// # Examples
///
@@ -196,8 +227,8 @@
/// An iterator method that reduces the iterator's elements to a single,
/// final value, starting from the back.
///
- /// This is the reverse version of [`fold()`]: it takes elements starting from
- /// the back of the iterator.
+ /// This is the reverse version of [`Iterator::fold()`]: it takes elements
+ /// starting from the back of the iterator.
///
/// `rfold()` takes two arguments: an initial value, and a closure with two
/// arguments: an 'accumulator', and an element. The closure returns the value that
@@ -214,8 +245,6 @@
/// Folding is useful whenever you have a collection of something, and want
/// to produce a single value from it.
///
- /// [`fold()`]: trait.Iterator.html#method.fold
- ///
/// # Examples
///
/// Basic usage:
@@ -307,11 +336,9 @@
P: FnMut(&Self::Item) -> bool,
{
#[inline]
- fn check<T>(
- mut predicate: impl FnMut(&T) -> bool,
- ) -> impl FnMut((), T) -> LoopState<(), T> {
+ fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
move |(), x| {
- if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+ if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
}
}
@@ -324,6 +351,9 @@
fn next_back(&mut self) -> Option<I::Item> {
(**self).next_back()
}
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ (**self).advance_back_by(n)
+ }
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
(**self).nth_back(n)
}
diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs
index ad87d09..33ace60 100644
--- a/library/core/src/iter/traits/exact_size.rs
+++ b/library/core/src/iter/traits/exact_size.rs
@@ -6,17 +6,14 @@
/// backwards, a good start is to know where the end is.
///
/// When implementing an `ExactSizeIterator`, you must also implement
-/// [`Iterator`]. When doing so, the implementation of [`size_hint`] *must*
-/// return the exact size of the iterator.
-///
-/// [`Iterator`]: trait.Iterator.html
-/// [`size_hint`]: trait.Iterator.html#method.size_hint
+/// [`Iterator`]. When doing so, the implementation of [`Iterator::size_hint`]
+/// *must* return the exact size of the iterator.
///
/// The [`len`] method has a default implementation, so you usually shouldn't
/// implement it. However, you may be able to provide a more performant
/// implementation than the default, so overriding it in this case makes sense.
///
-/// [`len`]: #method.len
+/// [`len`]: ExactSizeIterator::len
///
/// # Examples
///
@@ -72,17 +69,17 @@
/// Returns the exact length of the iterator.
///
/// The implementation ensures that the iterator will return exactly `len()`
- /// more times a `Some(T)` value, before returning `None`.
+ /// more times a [`Some(T)`] value, before returning [`None`].
/// This method has a default implementation, so you usually should not
/// implement it directly. However, if you can provide a more efficient
/// implementation, you can do so. See the [trait-level] docs for an
/// example.
///
- /// This function has the same safety guarantees as the [`size_hint`]
- /// function.
+ /// This function has the same safety guarantees as the
+ /// [`Iterator::size_hint`] function.
///
- /// [trait-level]: trait.ExactSizeIterator.html
- /// [`size_hint`]: trait.Iterator.html#method.size_hint
+ /// [trait-level]: ExactSizeIterator
+ /// [`Some(T)`]: Some
///
/// # Examples
///
@@ -108,8 +105,8 @@
/// Returns `true` if the iterator is empty.
///
- /// This method has a default implementation using `self.len()`, so you
- /// don't need to implement it yourself.
+ /// This method has a default implementation using
+ /// [`ExactSizeIterator::len()`], so you don't need to implement it yourself.
///
/// # Examples
///
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 10498f9..a1d8deb 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3,9 +3,8 @@
// can't split that into multiple files.
use crate::cmp::{self, Ordering};
-use crate::ops::{Add, Try};
+use crate::ops::{Add, ControlFlow, Try};
-use super::super::LoopState;
use super::super::TrustedRandomAccess;
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
use super::super::{FlatMap, Flatten};
@@ -22,8 +21,8 @@
/// generally, please see the [module-level documentation]. In particular, you
/// may want to know how to [implement `Iterator`][impl].
///
-/// [module-level documentation]: index.html
-/// [impl]: index.html#implementing-iterator
+/// [module-level documentation]: crate::iter
+/// [impl]: crate::iter#implementing-iterator
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
@@ -130,7 +129,7 @@
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next());
/// ```
- #[cfg_attr(not(bootstrap), lang = "next")]
+ #[lang = "next"]
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>;
@@ -212,7 +211,7 @@
/// returning the number of times it saw [`Some`]. Note that [`next`] has to be
/// called at least once even if the iterator does not have any elements.
///
- /// [`next`]: #tymethod.next
+ /// [`next`]: Iterator::next
///
/// # Overflow Behavior
///
@@ -285,6 +284,44 @@
self.fold(None, some)
}
+ /// Advances the iterator by `n` elements.
+ ///
+ /// This method will eagerly skip `n` elements by calling [`next`] up to `n`
+ /// times until [`None`] is encountered.
+ ///
+ /// `advance_by(n)` will return [`Ok(())`] if the iterator successfully advances by
+ /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number
+ /// of elements the iterator is advanced by before running out of elements (i.e. the
+ /// length of the iterator). Note that `k` is always less than `n`.
+ ///
+ /// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`].
+ ///
+ /// [`next`]: Iterator::next
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(iter_advance_by)]
+ ///
+ /// let a = [1, 2, 3, 4];
+ /// let mut iter = a.iter();
+ ///
+ /// assert_eq!(iter.advance_by(2), Ok(()));
+ /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.advance_by(0), Ok(()));
+ /// assert_eq!(iter.advance_by(100), Err(1)); // only `&4` was skipped
+ /// ```
+ #[inline]
+ #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ for i in 0..n {
+ self.next().ok_or(i)?;
+ }
+ Ok(())
+ }
+
/// Returns the `n`th element of the iterator.
///
/// Like most indexing operations, the count starts from zero, so `nth(0)`
@@ -326,14 +363,9 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
- while let Some(x) = self.next() {
- if n == 0 {
- return Some(x);
- }
- n -= 1;
- }
- None
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.advance_by(n).ok()?;
+ self.next()
}
/// Creates an iterator starting at the same point, but stepping by
@@ -449,9 +481,7 @@
/// }
/// ```
///
- /// [`once`]: fn.once.html
- /// [`Iterator`]: trait.Iterator.html
- /// [`IntoIterator`]: trait.IntoIterator.html
+ /// [`once`]: crate::iter::once
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -496,9 +526,6 @@
/// [`Iterator`] itself. For example, slices (`&[T]`) implement
/// [`IntoIterator`], and so can be passed to `zip()` directly:
///
- /// [`IntoIterator`]: trait.IntoIterator.html
- /// [`Iterator`]: trait.Iterator.html
- ///
/// ```
/// let s1 = &[1, 2, 3];
/// let s2 = &[4, 5, 6];
@@ -530,8 +557,8 @@
/// assert_eq!((2, 'o'), zipper[2]);
/// ```
///
- /// [`enumerate`]: #method.enumerate
- /// [`next`]: #tymethod.next
+ /// [`enumerate`]: Iterator::enumerate
+ /// [`next`]: Iterator::next
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
@@ -654,11 +681,9 @@
/// Creates an iterator which uses a closure to determine if an element
/// should be yielded.
///
- /// The closure must return `true` or `false`. `filter()` creates an
- /// iterator which calls this closure on each element. If the closure
- /// returns `true`, then the element is returned. If the closure returns
- /// `false`, it will try again, and call the closure on the next element,
- /// seeing if it passes the test.
+ /// Given an element the closure must return `true` or `false`. The returned
+ /// iterator will yield only the elements for which the closure returns
+ /// true.
///
/// # Examples
///
@@ -725,23 +750,15 @@
/// Creates an iterator that both filters and maps.
///
- /// The closure must return an [`Option<T>`]. `filter_map` creates an
- /// iterator which calls this closure on each element. If the closure
- /// returns [`Some(element)`][`Some`], then that element is returned. If the
- /// closure returns [`None`], it will try again, and call the closure on the
- /// next element, seeing if it will return [`Some`].
+ /// The returned iterator yields only the `value`s for which the supplied
+ /// closure returns `Some(value)`.
///
- /// Why `filter_map` and not just [`filter`] and [`map`]? The key is in this
- /// part:
+ /// `filter_map` can be used to make chains of [`filter`] and [`map`] more
+ /// concise. The example below shows how a `map().filter().map()` can be
+ /// shortened to a single call to `filter_map`.
///
- /// [`filter`]: #method.filter
- /// [`map`]: #method.map
- ///
- /// > If the closure returns [`Some(element)`][`Some`], then that element is returned.
- ///
- /// In other words, it removes the [`Option<T>`] layer automatically. If your
- /// mapping is already returning an [`Option<T>`] and you want to skip over
- /// [`None`]s, then `filter_map` is much, much nicer to use.
+ /// [`filter`]: Iterator::filter
+ /// [`map`]: Iterator::map
///
/// # Examples
///
@@ -802,7 +819,7 @@
///
/// [`usize`]: type@usize
/// [`usize::MAX`]: crate::usize::MAX
- /// [`zip`]: #method.zip
+ /// [`zip`]: Iterator::zip
///
/// # Examples
///
@@ -825,7 +842,7 @@
Enumerate::new(self)
}
- /// Creates an iterator which can use `peek` to look at the next element of
+ /// Creates an iterator which can use [`peek`] to look at the next element of
/// the iterator without consuming it.
///
/// Adds a [`peek`] method to an iterator. See its documentation for
@@ -837,8 +854,8 @@
/// anything other than fetching the next value) of the [`next`] method
/// will occur.
///
- /// [`peek`]: crate::iter::Peekable::peek
- /// [`next`]: #tymethod.next
+ /// [`peek`]: Peekable::peek
+ /// [`next`]: Iterator::next
///
/// # Examples
///
@@ -876,7 +893,7 @@
/// Creates an iterator that [`skip`]s elements based on a predicate.
///
- /// [`skip`]: #method.skip
+ /// [`skip`]: Iterator::skip
///
/// `skip_while()` takes a closure as an argument. It will call this
/// closure on each element of the iterator, and ignore elements
@@ -1043,8 +1060,8 @@
///
/// Here's the same example, but with [`take_while`] and [`map`]:
///
- /// [`take_while`]: #method.take_while
- /// [`map`]: #method.map
+ /// [`take_while`]: Iterator::take_while
+ /// [`map`]: Iterator::map
///
/// ```
/// let a = [-1i32, 4, 0, 1];
@@ -1104,7 +1121,7 @@
/// It is also not specified what this iterator returns after the first` None` is returned.
/// If you need fused iterator, use [`fuse`].
///
- /// [`fuse`]: #method.fuse
+ /// [`fuse`]: Iterator::fuse
#[inline]
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
@@ -1190,7 +1207,7 @@
/// An iterator adaptor similar to [`fold`] that holds internal state and
/// produces a new iterator.
///
- /// [`fold`]: #method.fold
+ /// [`fold`]: Iterator::fold
///
/// `scan()` takes two arguments: an initial value which seeds the internal
/// state, and a closure with two arguments, the first being a mutable
@@ -1246,8 +1263,8 @@
/// one item for each element, and `flat_map()`'s closure returns an
/// iterator for each element.
///
- /// [`map`]: #method.map
- /// [`flatten`]: #method.flatten
+ /// [`map`]: Iterator::map
+ /// [`flatten`]: Iterator::flatten
///
/// # Examples
///
@@ -1333,7 +1350,7 @@
/// two-dimensional and not one-dimensional. To get a one-dimensional
/// structure, you have to `flatten()` again.
///
- /// [`flat_map()`]: #method.flat_map
+ /// [`flat_map()`]: Iterator::flat_map
#[inline]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
fn flatten(self) -> Flatten<Self>
@@ -1640,7 +1657,7 @@
/// assert_eq!(Ok(vec![1, 3]), result);
/// ```
///
- /// [`iter`]: #tymethod.next
+ /// [`iter`]: Iterator::next
/// [`String`]: ../../std/string/struct.String.html
/// [`char`]: type@char
#[inline]
@@ -1661,8 +1678,8 @@
///
/// See also [`is_partitioned()`] and [`partition_in_place()`].
///
- /// [`is_partitioned()`]: #method.is_partitioned
- /// [`partition_in_place()`]: #method.partition_in_place
+ /// [`is_partitioned()`]: Iterator::is_partitioned
+ /// [`partition_in_place()`]: Iterator::partition_in_place
///
/// # Examples
///
@@ -1716,8 +1733,8 @@
///
/// See also [`is_partitioned()`] and [`partition()`].
///
- /// [`is_partitioned()`]: #method.is_partitioned
- /// [`partition()`]: #method.partition
+ /// [`is_partitioned()`]: Iterator::is_partitioned
+ /// [`partition()`]: Iterator::partition
///
/// # Examples
///
@@ -1779,8 +1796,8 @@
///
/// See also [`partition()`] and [`partition_in_place()`].
///
- /// [`partition()`]: #method.partition
- /// [`partition_in_place()`]: #method.partition_in_place
+ /// [`partition()`]: Iterator::partition
+ /// [`partition_in_place()`]: Iterator::partition_in_place
///
/// # Examples
///
@@ -1879,8 +1896,8 @@
/// This can also be thought of as the fallible form of [`for_each()`]
/// or as the stateless version of [`try_fold()`].
///
- /// [`for_each()`]: #method.for_each
- /// [`try_fold()`]: #method.try_fold
+ /// [`for_each()`]: Iterator::for_each
+ /// [`try_fold()`]: Iterator::try_fold
///
/// # Examples
///
@@ -1992,6 +2009,8 @@
/// // they're the same
/// assert_eq!(result, result2);
/// ```
+ #[doc(alias = "reduce")]
+ #[doc(alias = "inject")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn fold<B, F>(mut self, init: B, mut f: F) -> B
@@ -2006,11 +2025,13 @@
accum
}
- /// The same as [`fold()`](#method.fold), but uses the first element in the
+ /// The same as [`fold()`], but uses the first element in the
/// iterator as the initial value, folding every subsequent element into it.
- /// If the iterator is empty, return `None`; otherwise, return the result
+ /// If the iterator is empty, return [`None`]; otherwise, return the result
/// of the fold.
///
+ /// [`fold()`]: Iterator::fold
+ ///
/// # Example
///
/// Find the maximum value:
@@ -2088,12 +2109,12 @@
F: FnMut(Self::Item) -> bool,
{
#[inline]
- fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
move |(), x| {
- if f(x) { LoopState::Continue(()) } else { LoopState::Break(()) }
+ if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
}
}
- self.try_fold((), check(f)) == LoopState::Continue(())
+ self.try_fold((), check(f)) == ControlFlow::CONTINUE
}
/// Tests if any element of the iterator matches a predicate.
@@ -2141,13 +2162,13 @@
F: FnMut(Self::Item) -> bool,
{
#[inline]
- fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
move |(), x| {
- if f(x) { LoopState::Break(()) } else { LoopState::Continue(()) }
+ if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
}
}
- self.try_fold((), check(f)) == LoopState::Break(())
+ self.try_fold((), check(f)) == ControlFlow::BREAK
}
/// Searches for an element of an iterator that satisfies a predicate.
@@ -2201,11 +2222,9 @@
P: FnMut(&Self::Item) -> bool,
{
#[inline]
- fn check<T>(
- mut predicate: impl FnMut(&T) -> bool,
- ) -> impl FnMut((), T) -> LoopState<(), T> {
+ fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
move |(), x| {
- if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+ if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
}
}
@@ -2217,7 +2236,6 @@
///
/// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`.
///
- ///
/// # Examples
///
/// ```
@@ -2235,10 +2253,10 @@
F: FnMut(Self::Item) -> Option<B>,
{
#[inline]
- fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> LoopState<(), B> {
+ fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<B> {
move |(), x| match f(x) {
- Some(x) => LoopState::Break(x),
- None => LoopState::Continue(()),
+ Some(x) => ControlFlow::Break(x),
+ None => ControlFlow::CONTINUE,
}
}
@@ -2274,15 +2292,15 @@
R: Try<Ok = bool>,
{
#[inline]
- fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> LoopState<(), Result<T, R::Error>>
+ fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Error>>
where
F: FnMut(&T) -> R,
R: Try<Ok = bool>,
{
move |(), x| match f(&x).into_result() {
- Ok(false) => LoopState::Continue(()),
- Ok(true) => LoopState::Break(Ok(x)),
- Err(x) => LoopState::Break(Err(x)),
+ Ok(false) => ControlFlow::CONTINUE,
+ Ok(true) => ControlFlow::Break(Ok(x)),
+ Err(x) => ControlFlow::Break(Err(x)),
}
}
@@ -2352,10 +2370,14 @@
#[inline]
fn check<T>(
mut predicate: impl FnMut(T) -> bool,
- ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+ ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
// The addition might panic on overflow
move |i, x| {
- if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(Add::add(i, 1)) }
+ if predicate(x) {
+ ControlFlow::Break(i)
+ } else {
+ ControlFlow::Continue(Add::add(i, 1))
+ }
}
}
@@ -2411,10 +2433,10 @@
#[inline]
fn check<T>(
mut predicate: impl FnMut(T) -> bool,
- ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+ ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
move |i, x| {
let i = i - 1;
- if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(i) }
+ if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) }
}
}
@@ -2602,8 +2624,6 @@
/// This is only possible if the iterator has an end, so `rev()` only
/// works on [`DoubleEndedIterator`]s.
///
- /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
- ///
/// # Examples
///
/// ```
@@ -2634,7 +2654,7 @@
///
/// This function is, in some sense, the opposite of [`zip`].
///
- /// [`zip`]: #method.zip
+ /// [`zip`]: Iterator::zip
///
/// # Examples
///
@@ -2713,7 +2733,7 @@
/// This is useful when you have an iterator over `&T`, but you need an
/// iterator over `T`.
///
- /// [`clone`]: crate::clone::Clone::clone
+ /// [`clone`]: Clone::clone
///
/// # Examples
///
@@ -2831,7 +2851,7 @@
Product::product(self)
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another.
///
/// # Examples
@@ -2853,7 +2873,7 @@
self.cmp_by(other, |x, y| x.cmp(&y))
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another with respect to the specified comparison function.
///
/// # Examples
@@ -2905,7 +2925,7 @@
}
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another.
///
/// # Examples
@@ -2929,7 +2949,7 @@
self.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another with respect to the specified comparison function.
///
/// # Examples
@@ -2990,7 +3010,7 @@
}
}
- /// Determines if the elements of this `Iterator` are equal to those of
+ /// Determines if the elements of this [`Iterator`] are equal to those of
/// another.
///
/// # Examples
@@ -3009,7 +3029,7 @@
self.eq_by(other, |x, y| x == y)
}
- /// Determines if the elements of this `Iterator` are equal to those of
+ /// Determines if the elements of this [`Iterator`] are equal to those of
/// another with respect to the specified equality function.
///
/// # Examples
@@ -3050,7 +3070,7 @@
}
}
- /// Determines if the elements of this `Iterator` are unequal to those of
+ /// Determines if the elements of this [`Iterator`] are unequal to those of
/// another.
///
/// # Examples
@@ -3069,7 +3089,7 @@
!self.eq(other)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// less than those of another.
///
/// # Examples
@@ -3078,6 +3098,7 @@
/// assert_eq!([1].iter().lt([1].iter()), false);
/// assert_eq!([1].iter().lt([1, 2].iter()), true);
/// assert_eq!([1, 2].iter().lt([1].iter()), false);
+ /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn lt<I>(self, other: I) -> bool
@@ -3089,7 +3110,7 @@
self.partial_cmp(other) == Some(Ordering::Less)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// less or equal to those of another.
///
/// # Examples
@@ -3098,6 +3119,7 @@
/// assert_eq!([1].iter().le([1].iter()), true);
/// assert_eq!([1].iter().le([1, 2].iter()), true);
/// assert_eq!([1, 2].iter().le([1].iter()), false);
+ /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn le<I>(self, other: I) -> bool
@@ -3109,7 +3131,7 @@
matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// greater than those of another.
///
/// # Examples
@@ -3118,6 +3140,7 @@
/// assert_eq!([1].iter().gt([1].iter()), false);
/// assert_eq!([1].iter().gt([1, 2].iter()), false);
/// assert_eq!([1, 2].iter().gt([1].iter()), true);
+ /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn gt<I>(self, other: I) -> bool
@@ -3129,7 +3152,7 @@
self.partial_cmp(other) == Some(Ordering::Greater)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// greater than or equal to those of another.
///
/// # Examples
@@ -3138,6 +3161,7 @@
/// assert_eq!([1].iter().ge([1].iter()), true);
/// assert_eq!([1].iter().ge([1, 2].iter()), false);
/// assert_eq!([1, 2].iter().ge([1].iter()), true);
+ /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn ge<I>(self, other: I) -> bool
@@ -3197,7 +3221,7 @@
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// ```
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: Iterator::is_sorted
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
where
@@ -3226,7 +3250,7 @@
/// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see
/// its documentation for more information.
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: Iterator::is_sorted
///
/// # Examples
///
@@ -3248,6 +3272,8 @@
}
/// See [TrustedRandomAccess]
+ // The unusual name is to avoid name collisions in method resolution
+ // see #76479.
#[inline]
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
@@ -3268,6 +3294,9 @@
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ (**self).advance_by(n)
+ }
fn nth(&mut self, n: usize) -> Option<Self::Item> {
(**self).nth(n)
}
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index 3c893c0..0900676 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -2,14 +2,13 @@
///
/// Calling next on a fused iterator that has returned `None` once is guaranteed
/// to return [`None`] again. This trait should be implemented by all iterators
-/// that behave this way because it allows optimizing [`Iterator::fuse`].
+/// that behave this way because it allows optimizing [`Iterator::fuse()`].
///
/// Note: In general, you should not use `FusedIterator` in generic bounds if
-/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
+/// you need a fused iterator. Instead, you should just call [`Iterator::fuse()`]
/// on the iterator. If the iterator is already fused, the additional [`Fuse`]
/// wrapper will be a no-op with no performance penalty.
///
-/// [`Iterator::fuse`]: crate::iter::Iterator::fuse
/// [`Fuse`]: crate::iter::Fuse
#[stable(feature = "fused", since = "1.26.0")]
#[rustc_unsafe_specialization_marker]
@@ -24,21 +23,34 @@
/// (lower bound is equal to upper bound), or the upper bound is [`None`].
/// The upper bound must only be [`None`] if the actual iterator length is
/// larger than [`usize::MAX`]. In that case, the lower bound must be
-/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`.
+/// [`usize::MAX`], resulting in a [`Iterator::size_hint()`] of
+/// `(usize::MAX, None)`.
///
/// The iterator must produce exactly the number of elements it reported
/// or diverge before reaching the end.
///
/// # Safety
///
-/// This trait must only be implemented when the contract is upheld.
-/// Consumers of this trait must inspect [`.size_hint`]’s upper bound.
+/// This trait must only be implemented when the contract is upheld. Consumers
+/// of this trait must inspect [`Iterator::size_hint()`]’s upper bound.
///
/// [`usize::MAX`]: crate::usize::MAX
-/// [`.size_hint`]: crate::iter::Iterator::size_hint
#[unstable(feature = "trusted_len", issue = "37572")]
#[rustc_unsafe_specialization_marker]
pub unsafe trait TrustedLen: Iterator {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen + ?Sized> TrustedLen for &mut I {}
+
+/// An iterator that when yielding an item will have taken at least one element
+/// from its underlying [`SourceIter`].
+///
+/// Calling [`next()`] guarantees that at least one value of the iterator's underlying source
+/// has been moved out and the result of the iterator chain could be inserted in its place,
+/// assuming structural constraints of the source allow such an insertion.
+/// In other words this trait indicates that an iterator pipeline can be collected in place.
+///
+/// [`SourceIter`]: crate::iter::SourceIter
+/// [`next()`]: Iterator::next
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub unsafe trait InPlaceIterable: Iterator {}
diff --git a/library/core/src/iter/traits/mod.rs b/library/core/src/iter/traits/mod.rs
index efd1580..880f8d8 100644
--- a/library/core/src/iter/traits/mod.rs
+++ b/library/core/src/iter/traits/mod.rs
@@ -11,5 +11,7 @@
pub use self::exact_size::ExactSizeIterator;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::iterator::Iterator;
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub use self::marker::InPlaceIterable;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::marker::{FusedIterator, TrustedLen};
diff --git a/library/core/src/lazy.rs b/library/core/src/lazy.rs
index 5cf7217..2c51737 100644
--- a/library/core/src/lazy.rs
+++ b/library/core/src/lazy.rs
@@ -92,7 +92,7 @@
/// Returns `None` if the cell is empty.
#[unstable(feature = "once_cell", issue = "74465")]
pub fn get(&self) -> Option<&T> {
- // Safety: Safe due to `inner`'s invariant
+ // SAFETY: Safe due to `inner`'s invariant
unsafe { &*self.inner.get() }.as_ref()
}
@@ -101,7 +101,7 @@
/// Returns `None` if the cell is empty.
#[unstable(feature = "once_cell", issue = "74465")]
pub fn get_mut(&mut self) -> Option<&mut T> {
- // Safety: Safe because we have unique access
+ // SAFETY: Safe because we have unique access
unsafe { &mut *self.inner.get() }.as_mut()
}
@@ -129,13 +129,13 @@
/// ```
#[unstable(feature = "once_cell", issue = "74465")]
pub fn set(&self, value: T) -> Result<(), T> {
- // Safety: Safe because we cannot have overlapping mutable borrows
+ // SAFETY: Safe because we cannot have overlapping mutable borrows
let slot = unsafe { &*self.inner.get() };
if slot.is_some() {
return Err(value);
}
- // Safety: This is the only place where we set the slot, no races
+ // SAFETY: This is the only place where we set the slot, no races
// due to reentrancy/concurrency are possible, and we've
// checked that slot is currently `None`, so this write
// maintains the `inner`'s invariant.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 8270b73..22bf2b1 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -66,9 +66,7 @@
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
-#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)]
-#![feature(concat_idents)]
#![feature(const_alloc_layout)]
#![feature(const_discriminant)]
#![feature(const_checked_int_methods)]
@@ -77,17 +75,21 @@
#![feature(const_float_bits_conv)]
#![feature(const_overflowing_int_methods)]
#![feature(const_int_unchecked_arith)]
+#![feature(const_mut_refs)]
#![feature(const_int_pow)]
#![feature(constctlz)]
#![feature(const_panic)]
+#![feature(const_pin)]
#![feature(const_fn_union)]
+#![feature(const_fn)]
+#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
+#![cfg_attr(not(bootstrap), feature(const_fn_fn_ptr_basics))]
#![feature(const_generics)]
#![feature(const_option)]
#![feature(const_precise_live_drops)]
#![feature(const_ptr_offset)]
#![feature(const_ptr_offset_from)]
#![feature(const_raw_ptr_comparison)]
-#![feature(const_result)]
#![feature(const_slice_from_raw_parts)]
#![feature(const_slice_ptr_len)]
#![feature(const_size_of_val)]
@@ -99,13 +101,12 @@
#![feature(custom_inner_attributes)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
-#![cfg_attr(not(bootstrap), feature(doc_spotlight))]
+#![feature(doc_spotlight)]
#![feature(duration_consts_2)]
+#![feature(duration_saturating_ops)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
-#![feature(try_find)]
-#![feature(is_sorted)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(llvm_asm)]
@@ -117,7 +118,6 @@
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(prelude_import)]
-#![feature(ptr_as_uninit)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
@@ -131,8 +131,7 @@
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(variant_count)]
-#![feature(doc_alias)]
-#![feature(mmx_target_feature)]
+#![cfg_attr(bootstrap, feature(doc_alias))]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
@@ -148,8 +147,6 @@
#![feature(const_fn_transmute)]
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
-#![feature(maybe_uninit_slice)]
-#![feature(maybe_uninit_extra)]
#![feature(external_doc)]
#![feature(associated_type_bounds)]
#![feature(const_caller_location)]
@@ -169,34 +166,34 @@
#[macro_use]
mod internal_macros;
-#[path = "num/int_macros.rs"]
+#[path = "num/shells/int_macros.rs"]
#[macro_use]
mod int_macros;
-#[path = "num/i128.rs"]
+#[path = "num/shells/i128.rs"]
pub mod i128;
-#[path = "num/i16.rs"]
+#[path = "num/shells/i16.rs"]
pub mod i16;
-#[path = "num/i32.rs"]
+#[path = "num/shells/i32.rs"]
pub mod i32;
-#[path = "num/i64.rs"]
+#[path = "num/shells/i64.rs"]
pub mod i64;
-#[path = "num/i8.rs"]
+#[path = "num/shells/i8.rs"]
pub mod i8;
-#[path = "num/isize.rs"]
+#[path = "num/shells/isize.rs"]
pub mod isize;
-#[path = "num/u128.rs"]
+#[path = "num/shells/u128.rs"]
pub mod u128;
-#[path = "num/u16.rs"]
+#[path = "num/shells/u16.rs"]
pub mod u16;
-#[path = "num/u32.rs"]
+#[path = "num/shells/u32.rs"]
pub mod u32;
-#[path = "num/u64.rs"]
+#[path = "num/shells/u64.rs"]
pub mod u64;
-#[path = "num/u8.rs"]
+#[path = "num/shells/u8.rs"]
pub mod u8;
-#[path = "num/usize.rs"]
+#[path = "num/shells/usize.rs"]
pub mod usize;
#[path = "num/f32.rs"]
@@ -221,52 +218,41 @@
/* Core language traits */
pub mod borrow;
-#[cfg(not(test))] // See #65860
pub mod clone;
-#[cfg(not(test))] // See #65860
pub mod cmp;
pub mod convert;
-#[cfg(not(test))] // See #65860
pub mod default;
-#[cfg(not(test))] // See #65860
pub mod marker;
pub mod ops;
/* Core types and methods on primitives */
pub mod any;
-#[cfg(not(test))] // See #65860
pub mod array;
pub mod ascii;
pub mod cell;
pub mod char;
pub mod ffi;
-#[cfg(not(test))] // See #65860
pub mod iter;
#[unstable(feature = "once_cell", issue = "74465")]
pub mod lazy;
pub mod option;
pub mod panic;
pub mod panicking;
-#[cfg(not(test))] // See #65860
pub mod pin;
pub mod raw;
pub mod result;
pub mod sync;
-#[cfg(not(test))] // See #65860
pub mod fmt;
-#[cfg(not(test))] // See #65860
pub mod hash;
pub mod slice;
-#[cfg(not(test))] // See #65860
pub mod str;
pub mod time;
pub mod unicode;
/* Async */
-#[cfg(not(test))] // See #65860
pub mod future;
pub mod task;
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index d26f212..a1b0821 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -242,7 +242,7 @@
#[macro_export]
#[stable(feature = "matches_macro", since = "1.42.0")]
macro_rules! matches {
- ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
+ ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
match $expression {
$( $pattern )|+ $( if $guard )? => true,
_ => false
@@ -333,16 +333,16 @@
/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
/// formatted according to the specified format string and the result will be passed to the writer.
/// The writer may be any value with a `write_fmt` method; generally this comes from an
-/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro
-/// returns whatever the `write_fmt` method returns; commonly a [`std::fmt::Result`], or an
+/// implementation of either the [`fmt::Write`] or the [`io::Write`] trait. The macro
+/// returns whatever the `write_fmt` method returns; commonly a [`fmt::Result`], or an
/// [`io::Result`].
///
/// See [`std::fmt`] for more information on the format string syntax.
///
/// [`std::fmt`]: crate::fmt
-/// [`std::fmt::Write`]: crate::fmt::Write
-/// [`std::io::Write`]: ../std/io/trait.Write.html
-/// [`std::fmt::Result`]: crate::fmt::Result
+/// [`fmt::Write`]: crate::fmt::Write
+/// [`io::Write`]: ../std/io/trait.Write.html
+/// [`fmt::Result`]: crate::fmt::Result
/// [`io::Result`]: ../std/io/type.Result.html
///
/// # Examples
diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md
index 3ecfc43..a02e74d 100644
--- a/library/core/src/macros/panic.md
+++ b/library/core/src/macros/panic.md
@@ -5,12 +5,12 @@
an unrecoverable state.
This macro is the perfect way to assert conditions in example code and in
-tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
-and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
-to None or Err variants.
+tests. `panic!` is closely tied with the `unwrap` method of both
+[`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call
+`panic!` when they are set to [`None`] or [`Err`] variants.
This macro is used to inject panic into a Rust thread, causing the thread to
-panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
+panic entirely. Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type,
and the single-argument form of the `panic!` macro will be the value which
is transmitted.
@@ -24,11 +24,11 @@
See also the macro [`compile_error!`], for raising errors during compilation.
-[runwrap]: ../std/result/enum.Result.html#method.unwrap
-[`Option`]: ../std/option/enum.Option.html#method.unwrap
-[`Result`]: ../std/result/enum.Result.html
+[ounwrap]: Option::unwrap
+[runwrap]: Result::unwrap
+[`Box`]: ../std/boxed/struct.Box.html
+[`Any`]: crate::any::Any
[`format!`]: ../std/macro.format.html
-[`compile_error!`]: ../std/macro.compile_error.html
[book]: ../book/ch09-00-error-handling.html
# Current implementation
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 9326aaf..cdf7420 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -111,13 +111,13 @@
/// - `T` is not part of the type of any other fields
/// - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
///
-/// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow
-/// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized
+/// `Unsize` is used along with [`ops::CoerceUnsized`] to allow
+/// "user-defined" containers such as [`Rc`] to contain dynamically-sized
/// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce]
/// for more details.
///
-/// [coerceunsized]: ../ops/trait.CoerceUnsized.html
-/// [rc]: ../../std/rc/struct.Rc.html
+/// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized
+/// [`Rc`]: ../../std/rc/struct.Rc.html
/// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
/// [nomicon-coerce]: ../../nomicon/coercions.html
#[unstable(feature = "unsize", issue = "27732")]
@@ -368,11 +368,7 @@
///
/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
/// [`String`]: ../../std/string/struct.String.html
-/// [`Drop`]: ../../std/ops/trait.Drop.html
-/// [`size_of::<T>`]: ../../std/mem/fn.size_of.html
-/// [`Clone`]: ../clone/trait.Clone.html
-/// [`String`]: ../../std/string/struct.String.html
-/// [`i32`]: ../../std/primitive.i32.html
+/// [`size_of::<T>`]: crate::mem::size_of
/// [impls]: #implementors
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "copy"]
@@ -400,18 +396,18 @@
/// This trait is automatically implemented when the compiler determines
/// it's appropriate.
///
-/// The precise definition is: a type `T` is `Sync` if and only if `&T` is
-/// [`Send`][send]. In other words, if there is no possibility of
+/// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is
+/// [`Send`]. In other words, if there is no possibility of
/// [undefined behavior][ub] (including data races) when passing
/// `&T` references between threads.
///
-/// As one would expect, primitive types like [`u8`][u8] and [`f64`][f64]
-/// are all `Sync`, and so are simple aggregate types containing them,
-/// like tuples, structs and enums. More examples of basic `Sync`
+/// As one would expect, primitive types like [`u8`] and [`f64`]
+/// are all [`Sync`], and so are simple aggregate types containing them,
+/// like tuples, structs and enums. More examples of basic [`Sync`]
/// types include "immutable" types like `&T`, and those with simple
/// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and
-/// most other collection types. (Generic parameters need to be `Sync`
-/// for their container to be `Sync`.)
+/// most other collection types. (Generic parameters need to be [`Sync`]
+/// for their container to be [`Sync`].)
///
/// A somewhat surprising consequence of the definition is that `&mut T`
/// is `Sync` (if `T` is `Sync`) even though it seems like that might
@@ -421,15 +417,15 @@
/// of a data race.
///
/// Types that are not `Sync` are those that have "interior
-/// mutability" in a non-thread-safe form, such as [`cell::Cell`][cell]
-/// and [`cell::RefCell`][refcell]. These types allow for mutation of
+/// mutability" in a non-thread-safe form, such as [`Cell`][cell]
+/// and [`RefCell`][refcell]. These types allow for mutation of
/// their contents even through an immutable, shared reference. For
/// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires
/// only a shared reference [`&Cell<T>`][cell]. The method performs no
/// synchronization, thus [`Cell`][cell] cannot be `Sync`.
///
/// Another example of a non-`Sync` type is the reference-counting
-/// pointer [`rc::Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone
+/// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone
/// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way.
///
/// For cases when one does need thread-safe interior mutability,
@@ -445,24 +441,21 @@
/// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing
/// from `&T` to `&mut T` is invalid.
///
-/// See [the Nomicon](../../nomicon/send-and-sync.html) for more
-/// details about `Sync`.
+/// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`.
///
-/// [send]: trait.Send.html
-/// [u8]: ../../std/primitive.u8.html
-/// [f64]: ../../std/primitive.f64.html
/// [box]: ../../std/boxed/struct.Box.html
/// [vec]: ../../std/vec/struct.Vec.html
-/// [cell]: ../cell/struct.Cell.html
-/// [refcell]: ../cell/struct.RefCell.html
+/// [cell]: crate::cell::Cell
+/// [refcell]: crate::cell::RefCell
/// [rc]: ../../std/rc/struct.Rc.html
/// [arc]: ../../std/sync/struct.Arc.html
-/// [atomic data types]: ../sync/atomic/index.html
+/// [atomic data types]: crate::sync::atomic
/// [mutex]: ../../std/sync/struct.Mutex.html
/// [rwlock]: ../../std/sync/struct.RwLock.html
-/// [unsafecell]: ../cell/struct.UnsafeCell.html
+/// [unsafecell]: crate::cell::UnsafeCell
/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [transmute]: ../../std/mem/fn.transmute.html
+/// [transmute]: crate::mem::transmute
+/// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")]
#[lang = "sync"]
@@ -650,9 +643,9 @@
/// }
///
/// impl<R: ResType> ExternalResource<R> {
-/// fn new() -> ExternalResource<R> {
+/// fn new() -> Self {
/// let size_of_res = mem::size_of::<R>();
-/// ExternalResource {
+/// Self {
/// resource_handle: foreign_lib::new(size_of_res),
/// resource_type: PhantomData,
/// }
@@ -698,7 +691,7 @@
/// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute
/// between `DiscriminantKind::Discriminant` and `mem::Discriminant`.
///
-/// [`mem::Discriminant`]: https://doc.rust-lang.org/stable/core/mem/struct.Discriminant.html
+/// [`mem::Discriminant`]: crate::mem::Discriminant
#[unstable(
feature = "discriminant_kind",
issue = "none",
@@ -708,7 +701,7 @@
pub trait DiscriminantKind {
/// The type of the discriminant, which must satisfy the trait
/// bounds required by `mem::Discriminant`.
- #[cfg_attr(not(bootstrap), lang = "discriminant_type")]
+ #[lang = "discriminant_type"]
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
}
@@ -728,23 +721,23 @@
/// Types that can be safely moved after being pinned.
///
-/// Since Rust itself has no notion of immovable types, and considers moves
-/// (e.g., through assignment or [`mem::replace`]) to always be safe,
-/// this trait cannot prevent types from moving by itself.
+/// Rust itself has no notion of immovable types, and considers moves (e.g.,
+/// through assignment or [`mem::replace`]) to always be safe.
///
-/// Instead it is used to prevent moves through the type system,
-/// by controlling the behavior of pointers `P` wrapped in the [`Pin<P>`] wrapper,
-/// which "pin" the type in place by not allowing it to be moved out of them.
-/// See the [`pin module`] documentation for more information on pinning.
+/// The [`Pin`][Pin] type is used instead to prevent moves through the type
+/// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be
+/// moved out of. See the [`pin` module] documentation for more information on
+/// pinning.
///
-/// Implementing this trait lifts the restrictions of pinning off a type,
-/// which then allows it to move out with functions such as [`mem::replace`].
+/// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off
+/// the type, which then allows moving `T` out of [`Pin<P<T>>`][Pin] with
+/// functions such as [`mem::replace`].
///
/// `Unpin` has no consequence at all for non-pinned data. In particular,
/// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not
-/// just when `T: Unpin`). However, you cannot use
-/// [`mem::replace`] on data wrapped inside a [`Pin<P>`] because you cannot get the
-/// `&mut T` you need for that, and *that* is what makes this system work.
+/// just when `T: Unpin`). However, you cannot use [`mem::replace`] on data
+/// wrapped inside a [`Pin<P<T>>`][Pin] because you cannot get the `&mut T` you
+/// need for that, and *that* is what makes this system work.
///
/// So this, for example, can only be done on types implementing `Unpin`:
///
@@ -764,9 +757,9 @@
///
/// This trait is automatically implemented for almost every type.
///
-/// [`mem::replace`]: ../../std/mem/fn.replace.html
-/// [`Pin<P>`]: ../pin/struct.Pin.html
-/// [`pin module`]: ../../std/pin/index.html
+/// [`mem::replace`]: crate::mem::replace
+/// [Pin]: crate::pin::Pin
+/// [`pin` module]: crate::pin
#[stable(feature = "pin", since = "1.33.0")]
#[rustc_on_unimplemented(
on(_Self = "std::future::Future", note = "consider using `Box::pin`",),
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index e45aa86..d869394 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -15,50 +15,33 @@
/// be exposed through a public safe API.
/// Correspondingly, `ManuallyDrop::drop` is unsafe.
///
-/// # Examples
+/// # `ManuallyDrop` and drop order.
///
-/// This wrapper can be used to enforce a particular drop order on fields, regardless
-/// of how they are defined in the struct:
+/// Rust has a well-defined [drop order] of values. To make sure that fields or
+/// locals are dropped in a specific order, reorder the declarations such that
+/// the implicit drop order is the correct one.
///
-/// ```rust
-/// use std::mem::ManuallyDrop;
-/// struct Peach;
-/// struct Banana;
-/// struct Melon;
-/// struct FruitBox {
-/// // Immediately clear there’s something non-trivial going on with these fields.
-/// peach: ManuallyDrop<Peach>,
-/// melon: Melon, // Field that’s independent of the other two.
-/// banana: ManuallyDrop<Banana>,
-/// }
+/// It is possible to use `ManuallyDrop` to control the drop order, but this
+/// requires unsafe code and is hard to do correctly in the presence of
+/// unwinding.
///
-/// impl Drop for FruitBox {
-/// fn drop(&mut self) {
-/// unsafe {
-/// // Explicit ordering in which field destructors are run specified in the intuitive
-/// // location – the destructor of the structure containing the fields.
-/// // Moreover, one can now reorder fields within the struct however much they want.
-/// ManuallyDrop::drop(&mut self.peach);
-/// ManuallyDrop::drop(&mut self.banana);
-/// }
-/// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
-/// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
-/// }
+/// For example, if you want to make sure that a specific field is dropped after
+/// the others, make it the last field of a struct:
+///
+/// ```
+/// struct Context;
+///
+/// struct Widget {
+/// children: Vec<Widget>,
+/// // `context` will be dropped after `children`.
+/// // Rust guarantees that fields are dropped in the order of declaration.
+/// context: Context,
/// }
/// ```
///
-/// However, care should be taken when using this pattern as it can lead to *leak amplification*.
-/// In this example, if the `Drop` implementation for `Peach` were to panic, the `banana` field
-/// would also be leaked.
-///
-/// In contrast, the automatically-generated compiler drop implementation would have ensured
-/// that all fields are dropped even in the presence of panics. This is especially important when
-/// working with [pinned] data, where reusing the memory without calling the destructor could lead
-/// to Undefined Behaviour.
-///
+/// [drop order]: https://doc.rust-lang.org/reference/destructors.html
/// [`mem::zeroed`]: crate::mem::zeroed
/// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
-/// [pinned]: crate::pin
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -74,8 +57,12 @@
///
/// ```rust
/// use std::mem::ManuallyDrop;
- /// ManuallyDrop::new(Box::new(()));
+ /// let mut x = ManuallyDrop::new(String::from("Hello World!"));
+ /// x.truncate(5); // You can still safely operate on the value
+ /// assert_eq!(*x, "Hello");
+ /// // But `Drop` will not be run here
/// ```
+ #[must_use = "if you don't need the wrapper, you can use `mem::forget` instead"]
#[stable(feature = "manually_drop", since = "1.20.0")]
#[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
#[inline(always)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index d2d65fd..e629d28 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -2,8 +2,7 @@
use crate::fmt;
use crate::intrinsics;
use crate::mem::ManuallyDrop;
-
-// ignore-tidy-undocumented-unsafe
+use crate::ptr;
/// A wrapper type to construct uninitialized instances of `T`.
///
@@ -281,7 +280,7 @@
/// # Examples
///
/// ```no_run
- /// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
+ /// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice)]
///
/// use std::mem::MaybeUninit;
///
@@ -293,7 +292,7 @@
/// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
/// unsafe {
/// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
- /// MaybeUninit::slice_get_ref(&buf[..len])
+ /// MaybeUninit::slice_assume_init_ref(&buf[..len])
/// }
/// }
///
@@ -303,17 +302,10 @@
#[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
#[inline(always)]
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
+ // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
}
- /// A promotable constant, equivalent to `uninit()`.
- #[unstable(
- feature = "internal_uninit_const",
- issue = "none",
- reason = "hack to work around promotability"
- )]
- pub const UNINIT: Self = Self::uninit();
-
/// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
/// filled with `0` bytes. It depends on `T` whether that already makes for
/// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
@@ -354,6 +346,7 @@
#[rustc_diagnostic_item = "maybe_uninit_zeroed"]
pub fn zeroed() -> MaybeUninit<T> {
let mut u = MaybeUninit::<T>::uninit();
+ // SAFETY: `u.as_mut_ptr()` points to allocated memory.
unsafe {
u.as_mut_ptr().write_bytes(0u8, 1);
}
@@ -367,10 +360,9 @@
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
#[inline(always)]
pub fn write(&mut self, val: T) -> &mut T {
- unsafe {
- self.value = ManuallyDrop::new(val);
- self.get_mut()
- }
+ *self = MaybeUninit::new(val);
+ // SAFETY: We just initialized this value.
+ unsafe { self.assume_init_mut() }
}
/// Gets a pointer to the contained value. Reading from this pointer or turning it
@@ -472,6 +464,8 @@
/// *immediate* undefined behavior, but will cause undefined behavior with most
/// safe operations (including dropping it).
///
+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
+ ///
/// # Examples
///
/// Correct usage of this method:
@@ -520,8 +514,8 @@
/// this initialization invariant.
///
/// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
- /// multiple copies of the data (by calling `read` multiple times, or first
- /// calling `read` and then [`assume_init`]), it is your responsibility
+ /// multiple copies of the data (by calling `assume_init_read` multiple times, or first
+ /// calling `assume_init_read` and then [`assume_init`]), it is your responsibility
/// to ensure that that data may indeed be duplicated.
///
/// [inv]: #initialization-invariant
@@ -537,16 +531,16 @@
///
/// let mut x = MaybeUninit::<u32>::uninit();
/// x.write(13);
- /// let x1 = unsafe { x.read() };
+ /// let x1 = unsafe { x.assume_init_read() };
/// // `u32` is `Copy`, so we may read multiple times.
- /// let x2 = unsafe { x.read() };
+ /// let x2 = unsafe { x.assume_init_read() };
/// assert_eq!(x1, x2);
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
/// x.write(None);
- /// let x1 = unsafe { x.read() };
+ /// let x1 = unsafe { x.assume_init_read() };
/// // Duplicating a `None` value is okay, so we may read multiple times.
- /// let x2 = unsafe { x.read() };
+ /// let x2 = unsafe { x.assume_init_read() };
/// assert_eq!(x1, x2);
/// ```
///
@@ -558,14 +552,14 @@
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
/// x.write(Some(vec![0,1,2]));
- /// let x1 = unsafe { x.read() };
- /// let x2 = unsafe { x.read() };
+ /// let x1 = unsafe { x.assume_init_read() };
+ /// let x2 = unsafe { x.assume_init_read() };
/// // We now created two copies of the same vector, leading to a double-free ā ļø when
/// // they both get dropped!
/// ```
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
#[inline(always)]
- pub unsafe fn read(&self) -> T {
+ pub unsafe fn assume_init_read(&self) -> T {
// SAFETY: the caller must guarantee that `self` is initialized.
// Reading from `self.as_ptr()` is safe since `self` should be initialized.
unsafe {
@@ -574,6 +568,34 @@
}
}
+ /// Drops the contained value in place.
+ ///
+ /// If you have ownership of the `MaybeUninit`, you can use [`assume_init`] instead.
+ ///
+ /// # Safety
+ ///
+ /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is
+ /// in an initialized state. Calling this when the content is not yet fully
+ /// initialized causes undefined behavior.
+ ///
+ /// On top of that, all additional invariants of the type `T` must be
+ /// satisfied, as the `Drop` implementation of `T` (or its members) may
+ /// rely on this. For example, a `1`-initialized [`Vec<T>`] is considered
+ /// initialized (under the current implementation; this does not constitute
+ /// a stable guarantee) because the only requirement the compiler knows
+ /// about it is that the data pointer must be non-null. Dropping such a
+ /// `Vec<T>` however will cause undefined behaviour.
+ ///
+ /// [`assume_init`]: MaybeUninit::assume_init
+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
+ #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
+ pub unsafe fn assume_init_drop(&mut self) {
+ // SAFETY: the caller must guarantee that `self` is initialized and
+ // satisfies all invariants of `T`.
+ // Dropping the value in place is safe if that is the case.
+ unsafe { ptr::drop_in_place(self.as_mut_ptr()) }
+ }
+
/// Gets a shared reference to the contained value.
///
/// This can be useful when we want to access a `MaybeUninit` that has been
@@ -600,8 +622,8 @@
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
/// // create a shared reference to it:
/// let x: &Vec<u32> = unsafe {
- /// // Safety: `x` has been initialized.
- /// x.get_ref()
+ /// // SAFETY: `x` has been initialized.
+ /// x.assume_init_ref()
/// };
/// assert_eq!(x, &vec![1, 2, 3]);
/// ```
@@ -613,7 +635,7 @@
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
- /// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
+ /// let x_vec: &Vec<u32> = unsafe { x.assume_init_ref() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ā ļø
/// ```
///
@@ -624,14 +646,14 @@
/// let b = MaybeUninit::<Cell<bool>>::uninit();
/// // Initialize the `MaybeUninit` using `Cell::set`:
/// unsafe {
- /// b.get_ref().set(true);
- /// // ^^^^^^^^^^^
- /// // Reference to an uninitialized `Cell<bool>`: UB!
+ /// b.assume_init_ref().set(true);
+ /// // ^^^^^^^^^^^^^^^
+ /// // Reference to an uninitialized `Cell<bool>`: UB!
/// }
/// ```
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
#[inline(always)]
- pub unsafe fn get_ref(&self) -> &T {
+ pub unsafe fn assume_init_ref(&self) -> &T {
// SAFETY: the caller must guarantee that `self` is initialized.
// This also means that `self` must be a `value` variant.
unsafe {
@@ -650,7 +672,7 @@
///
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
- /// is in an initialized state. For instance, `.get_mut()` cannot be used to
+ /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to
/// initialize a `MaybeUninit`.
///
/// # Examples
@@ -677,8 +699,8 @@
/// // To assert our buffer has been initialized without copying it, we upgrade
/// // the `&mut MaybeUninit<[u8; 2048]>` to a `&mut [u8; 2048]`:
/// let buf: &mut [u8; 2048] = unsafe {
- /// // Safety: `buf` has been initialized.
- /// buf.get_mut()
+ /// // SAFETY: `buf` has been initialized.
+ /// buf.assume_init_mut()
/// };
///
/// // Now we can use `buf` as a normal slice:
@@ -691,7 +713,7 @@
///
/// ### *Incorrect* usages of this method:
///
- /// You cannot use `.get_mut()` to initialize a value:
+ /// You cannot use `.assume_init_mut()` to initialize a value:
///
/// ```rust,no_run
/// #![feature(maybe_uninit_ref)]
@@ -699,7 +721,7 @@
///
/// let mut b = MaybeUninit::<bool>::uninit();
/// unsafe {
- /// *b.get_mut() = true;
+ /// *b.assume_init_mut() = true;
/// // We have created a (mutable) reference to an uninitialized `bool`!
/// // This is undefined behavior. ā ļø
/// }
@@ -716,8 +738,8 @@
/// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
/// {
/// let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
- /// reader.read_exact(unsafe { buffer.get_mut() })?;
- /// // ^^^^^^^^^^^^^^^^
+ /// reader.read_exact(unsafe { buffer.assume_init_mut() })?;
+ /// // ^^^^^^^^^^^^^^^^^^^^^^^^
/// // (mutable) reference to uninitialized memory!
/// // This is undefined behavior.
/// Ok(unsafe { buffer.assume_init() })
@@ -737,23 +759,23 @@
///
/// let foo: Foo = unsafe {
/// let mut foo = MaybeUninit::<Foo>::uninit();
- /// ptr::write(&mut foo.get_mut().a as *mut u32, 1337);
- /// // ^^^^^^^^^^^^^
+ /// ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337);
+ /// // ^^^^^^^^^^^^^^^^^^^^^
/// // (mutable) reference to uninitialized memory!
/// // This is undefined behavior.
- /// ptr::write(&mut foo.get_mut().b as *mut u8, 42);
- /// // ^^^^^^^^^^^^^
+ /// ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42);
+ /// // ^^^^^^^^^^^^^^^^^^^^^
/// // (mutable) reference to uninitialized memory!
/// // This is undefined behavior.
/// foo.assume_init()
/// };
/// ```
- // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
+ // FIXME(#76092): We currently rely on the above being incorrect, i.e., we have references
// to uninitialized data (e.g., in `libcore/fmt/float.rs`). We should make
// a final decision about the rules before stabilization.
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
#[inline(always)]
- pub unsafe fn get_mut(&mut self) -> &mut T {
+ pub unsafe fn assume_init_mut(&mut self) -> &mut T {
// SAFETY: the caller must guarantee that `self` is initialized.
// This also means that `self` must be a `value` variant.
unsafe {
@@ -769,9 +791,13 @@
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
- #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
+ ///
+ /// See [`assume_init_ref`] for more details and examples.
+ ///
+ /// [`assume_init_ref`]: MaybeUninit::assume_init_ref
+ #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
- pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
+ pub unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
// SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that
// `slice` is initialized, and`MaybeUninit` is guaranteed to have the same layout as `T`.
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
@@ -786,9 +812,13 @@
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
- #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
+ ///
+ /// See [`assume_init_mut`] for more details and examples.
+ ///
+ /// [`assume_init_mut`]: MaybeUninit::assume_init_mut
+ #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
- pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
+ pub unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
@@ -797,14 +827,14 @@
/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
- pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
+ pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
this as *const [MaybeUninit<T>] as *const T
}
/// Gets a mutable pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
- pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
+ pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this as *mut [MaybeUninit<T>] as *mut T
}
}
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 9107c57..aa1b552 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -31,10 +31,10 @@
/// forever in an unreachable state. However, it does not guarantee that pointers
/// to this memory will remain valid.
///
-/// * If you want to leak memory, see [`Box::leak`][leak].
-/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw].
+/// * If you want to leak memory, see [`Box::leak`].
+/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`].
/// * If you want to dispose of a value properly, running its destructor, see
-/// [`mem::drop`][drop].
+/// [`mem::drop`].
///
/// # Safety
///
@@ -132,28 +132,22 @@
/// ownership to `s` — the final step of interacting with `v` to dispose of it without
/// running its destructor is entirely avoided.
///
-/// [drop]: fn.drop.html
-/// [uninit]: fn.uninitialized.html
-/// [clone]: ../clone/trait.Clone.html
-/// [swap]: fn.swap.html
-/// [box]: ../../std/boxed/struct.Box.html
-/// [leak]: ../../std/boxed/struct.Box.html#method.leak
-/// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
+/// [`Box`]: ../../std/boxed/struct.Box.html
+/// [`Box::leak`]: ../../std/boxed/struct.Box.html#method.leak
+/// [`Box::into_raw`]: ../../std/boxed/struct.Box.html#method.into_raw
+/// [`mem::drop`]: drop
/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [`ManuallyDrop`]: struct.ManuallyDrop.html
#[inline]
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn forget<T>(t: T) {
- ManuallyDrop::new(t);
+ let _ = ManuallyDrop::new(t);
}
/// Like [`forget`], but also accepts unsized values.
///
/// This function is just a shim intended to be removed when the `unsized_locals` feature gets
/// stabilized.
-///
-/// [`forget`]: fn.forget.html
#[inline]
#[unstable(feature = "forget_unsized", issue = "none")]
pub fn forget_unsized<T: ?Sized>(t: T) {
@@ -301,7 +295,7 @@
/// assert_eq!(2, mem::size_of::<ExampleUnion>());
/// ```
///
-/// [alignment]: ./fn.align_of.html
+/// [alignment]: align_of
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
@@ -365,7 +359,6 @@
/// [slice]: ../../std/primitive.slice.html
/// [trait object]: ../../book/ch17-02-trait-objects.html
/// [extern type]: ../../unstable-book/language-features/extern-types.html
-/// [`size_of_val`]: ../../core/mem/fn.size_of_val.html
///
/// # Examples
///
@@ -501,7 +494,6 @@
/// [slice]: ../../std/primitive.slice.html
/// [trait object]: ../../book/ch17-02-trait-objects.html
/// [extern type]: ../../unstable-book/language-features/extern-types.html
-/// [`align_of_val`]: ../../core/mem/fn.align_of_val.html
///
/// # Examples
///
@@ -540,7 +532,7 @@
/// `needs_drop` explicitly. Types like [`HashMap`], on the other hand, have to drop
/// values one at a time and should use this API.
///
-/// [`drop_in_place`]: ../ptr/fn.drop_in_place.html
+/// [`drop_in_place`]: crate::ptr::drop_in_place
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
///
/// # Examples
@@ -595,9 +587,9 @@
/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
/// It is useful for FFI sometimes, but should generally be avoided.
///
-/// [zeroed]: union.MaybeUninit.html#method.zeroed
+/// [zeroed]: MaybeUninit::zeroed
/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [inv]: union.MaybeUninit.html#initialization-invariant
+/// [inv]: MaybeUninit#initialization-invariant
///
/// # Examples
///
@@ -650,10 +642,10 @@
/// (Notice that the rules around uninitialized integers are not finalized yet, but
/// until they are, it is advisable to avoid them.)
///
-/// [`MaybeUninit<T>`]: union.MaybeUninit.html
-/// [uninit]: union.MaybeUninit.html#method.uninit
-/// [assume_init]: union.MaybeUninit.html#method.assume_init
-/// [inv]: union.MaybeUninit.html#initialization-invariant
+/// [`MaybeUninit<T>`]: MaybeUninit
+/// [uninit]: MaybeUninit::uninit
+/// [assume_init]: MaybeUninit::assume_init
+/// [inv]: MaybeUninit#initialization-invariant
#[inline(always)]
#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -686,9 +678,6 @@
/// assert_eq!(42, x);
/// assert_eq!(5, y);
/// ```
-///
-/// [`replace`]: fn.replace.html
-/// [`take`]: fn.take.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
@@ -754,10 +743,6 @@
/// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
/// assert_eq!(buffer.buf.len(), 0);
/// ```
-///
-/// [`Clone`]: ../../std/clone/trait.Clone.html
-/// [`replace`]: fn.replace.html
-/// [`swap`]: fn.swap.html
#[inline]
#[stable(feature = "mem_take", since = "1.40.0")]
pub fn take<T: Default>(dest: &mut T) -> T {
@@ -822,10 +807,6 @@
/// assert_eq!(buffer.replace_index(0, 2), 0);
/// assert_eq!(buffer.buf[0], 2);
/// ```
-///
-/// [`Clone`]: ../../std/clone/trait.Clone.html
-/// [`swap`]: fn.swap.html
-/// [`take`]: fn.take.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
@@ -851,7 +832,7 @@
/// Because `_x` is moved into the function, it is automatically dropped before
/// the function returns.
///
-/// [drop]: ../ops/trait.Drop.html
+/// [drop]: Drop
///
/// # Examples
///
@@ -894,8 +875,7 @@
/// println!("x: {}, y: {}", x, y.0); // still available
/// ```
///
-/// [`RefCell`]: ../../std/cell/struct.RefCell.html
-/// [`Copy`]: ../../std/marker/trait.Copy.html
+/// [`RefCell`]: crate::cell::RefCell
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) {}
@@ -914,7 +894,6 @@
/// `T`.
///
/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [size_of]: fn.size_of.html
///
/// # Examples
///
@@ -960,8 +939,6 @@
/// Opaque type representing the discriminant of an enum.
///
/// See the [`discriminant`] function in this module for more information.
-///
-/// [`discriminant`]: fn.discriminant.html
#[stable(feature = "discriminant_value", since = "1.21.0")]
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs
index 6f16b93..6a1a1e1 100644
--- a/library/core/src/num/bignum.rs
+++ b/library/core/src/num/bignum.rs
@@ -20,7 +20,6 @@
#![macro_use]
use crate::intrinsics;
-use crate::mem;
/// Arithmetic operations required by bignums.
pub trait FullOps: Sized {
@@ -58,25 +57,22 @@
// This cannot overflow;
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
// FIXME: will LLVM optimize this into ADC or similar?
- let nbits = mem::size_of::<$ty>() * 8;
let v = (self as $bigty) * (other as $bigty) + (carry as $bigty);
- ((v >> nbits) as $ty, v as $ty)
+ ((v >> <$ty>::BITS) as $ty, v as $ty)
}
fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) {
// This cannot overflow;
// the output is between `0` and `2^nbits * (2^nbits - 1)`.
- let nbits = mem::size_of::<$ty>() * 8;
let v = (self as $bigty) * (other as $bigty) + (other2 as $bigty) +
(carry as $bigty);
- ((v >> nbits) as $ty, v as $ty)
+ ((v >> <$ty>::BITS) as $ty, v as $ty)
}
fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) {
debug_assert!(borrow < other);
// This cannot overflow; the output is between `0` and `other * (2^nbits - 1)`.
- let nbits = mem::size_of::<$ty>() * 8;
- let lhs = ((borrow as $bigty) << nbits) | (self as $bigty);
+ let lhs = ((borrow as $bigty) << <$ty>::BITS) | (self as $bigty);
let rhs = other as $bigty;
((lhs / rhs) as $ty, (lhs % rhs) as $ty)
}
@@ -128,13 +124,11 @@
/// Makes a bignum from `u64` value.
pub fn from_u64(mut v: u64) -> $name {
- use crate::mem;
-
let mut base = [0; $n];
let mut sz = 0;
while v > 0 {
base[sz] = v as $ty;
- v >>= mem::size_of::<$ty>() * 8;
+ v >>= <$ty>::BITS;
sz += 1;
}
$name { size: sz, base: base }
@@ -150,9 +144,7 @@
/// Returns the `i`-th bit where bit 0 is the least significant one.
/// In other words, the bit with weight `2^i`.
pub fn get_bit(&self, i: usize) -> u8 {
- use crate::mem;
-
- let digitbits = mem::size_of::<$ty>() * 8;
+ let digitbits = <$ty>::BITS as usize;
let d = i / digitbits;
let b = i % digitbits;
((self.base[d] >> b) & 1) as u8
@@ -166,8 +158,6 @@
/// Returns the number of bits necessary to represent this value. Note that zero
/// is considered to need 0 bits.
pub fn bit_length(&self) -> usize {
- use crate::mem;
-
// Skip over the most significant digits which are zero.
let digits = self.digits();
let zeros = digits.iter().rev().take_while(|&&x| x == 0).count();
@@ -180,7 +170,7 @@
}
// This could be optimized with leading_zeros() and bit shifts, but that's
// probably not worth the hassle.
- let digitbits = mem::size_of::<$ty>() * 8;
+ let digitbits = <$ty>::BITS as usize;
let mut i = nonzero.len() * digitbits - 1;
while self.get_bit(i) == 0 {
i -= 1;
@@ -265,9 +255,7 @@
/// Multiplies itself by `2^bits` and returns its own mutable reference.
pub fn mul_pow2(&mut self, bits: usize) -> &mut $name {
- use crate::mem;
-
- let digitbits = mem::size_of::<$ty>() * 8;
+ let digitbits = <$ty>::BITS as usize;
let digits = bits / digitbits;
let bits = bits % digitbits;
@@ -393,13 +381,11 @@
/// Divide self by another bignum, overwriting `q` with the quotient and `r` with the
/// remainder.
pub fn div_rem(&self, d: &$name, q: &mut $name, r: &mut $name) {
- use crate::mem;
-
// Stupid slow base-2 long division taken from
// https://en.wikipedia.org/wiki/Division_algorithm
// FIXME use a greater base ($ty) for the long division.
assert!(!d.is_zero());
- let digitbits = mem::size_of::<$ty>() * 8;
+ let digitbits = <$ty>::BITS as usize;
for digit in &mut q.base[..] {
*digit = 0;
}
@@ -462,10 +448,8 @@
impl crate::fmt::Debug for $name {
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
- use crate::mem;
-
let sz = if self.size < 1 { 1 } else { self.size };
- let digitlen = mem::size_of::<$ty>() * 2;
+ let digitlen = <$ty>::BITS as usize / 4;
write!(f, "{:#x}", self.base[sz - 1])?;
for &v in self.base[..sz - 1].iter().rev() {
diff --git a/library/core/src/num/dec2flt/algorithm.rs b/library/core/src/num/dec2flt/algorithm.rs
index aaeb4d8..a5fbdc6 100644
--- a/library/core/src/num/dec2flt/algorithm.rs
+++ b/library/core/src/num/dec2flt/algorithm.rs
@@ -60,12 +60,19 @@
fn set_cw(cw: u16) {
// SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
// any `u16`
- unsafe { llvm_asm!("fldcw $0" :: "m" (cw) :: "volatile") }
+ unsafe {
+ asm!(
+ "fldcw ({})",
+ in(reg) &cw,
+ // FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9.
+ options(att_syntax, nostack),
+ )
+ }
}
/// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`.
pub fn set_precision<T>() -> FPUControlWord {
- let cw = 0u16;
+ let mut cw = 0_u16;
// Compute the value for the Precision Control field that is appropriate for `T`.
let cw_precision = match size_of::<T>() {
@@ -78,7 +85,14 @@
// `FPUControlWord` structure is dropped
// SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
// any `u16`
- unsafe { llvm_asm!("fnstcw $0" : "=*m" (&cw) ::: "volatile") }
+ unsafe {
+ asm!(
+ "fnstcw ({})",
+ in(reg) &mut cw,
+ // FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9.
+ options(att_syntax, nostack),
+ )
+ }
// Set the control word to the desired precision. This is achieved by masking away the old
// precision (bits 8 and 9, 0x300) and replacing it with the precision flag computed above.
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index c83c6b0..6f3a3a8 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -167,9 +167,15 @@
/// This error is used as the error type for the [`FromStr`] implementation
/// for [`f32`] and [`f64`].
///
-/// [`FromStr`]: ../str/trait.FromStr.html
-/// [`f32`]: ../../std/primitive.f32.html
-/// [`f64`]: ../../std/primitive.f64.html
+/// # Example
+///
+/// ```
+/// use std::str::FromStr;
+///
+/// if let Err(e) = f64::from_str("a.12") {
+/// println!("Failed conversion to f64: {}", e);
+/// }
+/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
new file mode 100644
index 0000000..aab1715
--- /dev/null
+++ b/library/core/src/num/error.rs
@@ -0,0 +1,151 @@
+//! Error types for conversion to integral types.
+
+use crate::convert::Infallible;
+use crate::fmt;
+
+/// The error type returned when a checked integral type conversion fails.
+#[stable(feature = "try_from", since = "1.34.0")]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct TryFromIntError(pub(crate) ());
+
+impl TryFromIntError {
+ #[unstable(
+ feature = "int_error_internals",
+ reason = "available through Error trait and this method should \
+ not be exposed publicly",
+ issue = "none"
+ )]
+ #[doc(hidden)]
+ pub fn __description(&self) -> &str {
+ "out of range integral type conversion attempted"
+ }
+}
+
+#[stable(feature = "try_from", since = "1.34.0")]
+impl fmt::Display for TryFromIntError {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.__description().fmt(fmt)
+ }
+}
+
+#[stable(feature = "try_from", since = "1.34.0")]
+impl From<Infallible> for TryFromIntError {
+ fn from(x: Infallible) -> TryFromIntError {
+ match x {}
+ }
+}
+
+#[unstable(feature = "never_type", issue = "35121")]
+impl From<!> for TryFromIntError {
+ fn from(never: !) -> TryFromIntError {
+ // Match rather than coerce to make sure that code like
+ // `From<Infallible> for TryFromIntError` above will keep working
+ // when `Infallible` becomes an alias to `!`.
+ match never {}
+ }
+}
+
+/// An error which can be returned when parsing an integer.
+///
+/// This error is used as the error type for the `from_str_radix()` functions
+/// on the primitive integer types, such as [`i8::from_str_radix`].
+///
+/// # Potential causes
+///
+/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
+/// in the string e.g., when it is obtained from the standard input.
+/// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
+///
+/// [`str.trim()`]: ../../std/primitive.str.html#method.trim
+/// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
+///
+/// # Example
+///
+/// ```
+/// if let Err(e) = i32::from_str_radix("a12", 10) {
+/// println!("Failed conversion to i32: {}", e);
+/// }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseIntError {
+ pub(super) kind: IntErrorKind,
+}
+
+/// Enum to store the various types of errors that can cause parsing an integer to fail.
+///
+/// # Example
+///
+/// ```
+/// #![feature(int_error_matching)]
+///
+/// # fn main() {
+/// if let Err(e) = i32::from_str_radix("a12", 10) {
+/// println!("Failed conversion to i32: {:?}", e.kind());
+/// }
+/// # }
+/// ```
+#[unstable(
+ feature = "int_error_matching",
+ reason = "it can be useful to match errors when making error messages \
+ for integer parsing",
+ issue = "22639"
+)]
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum IntErrorKind {
+ /// Value being parsed is empty.
+ ///
+ /// Among other causes, this variant will be constructed when parsing an empty string.
+ Empty,
+ /// Contains an invalid digit.
+ ///
+ /// Among other causes, this variant will be constructed when parsing a string that
+ /// contains a letter.
+ InvalidDigit,
+ /// Integer is too large to store in target integer type.
+ Overflow,
+ /// Integer is too small to store in target integer type.
+ Underflow,
+ /// Value was Zero
+ ///
+ /// This variant will be emitted when the parsing string has a value of zero, which
+ /// would be illegal for non-zero types.
+ Zero,
+}
+
+impl ParseIntError {
+ /// Outputs the detailed cause of parsing an integer failing.
+ #[unstable(
+ feature = "int_error_matching",
+ reason = "it can be useful to match errors when making error messages \
+ for integer parsing",
+ issue = "22639"
+ )]
+ pub fn kind(&self) -> &IntErrorKind {
+ &self.kind
+ }
+ #[unstable(
+ feature = "int_error_internals",
+ reason = "available through Error trait and this method should \
+ not be exposed publicly",
+ issue = "none"
+ )]
+ #[doc(hidden)]
+ pub fn __description(&self) -> &str {
+ match self.kind {
+ IntErrorKind::Empty => "cannot parse integer from empty string",
+ IntErrorKind::InvalidDigit => "invalid digit found in string",
+ IntErrorKind::Overflow => "number too large to fit in target type",
+ IntErrorKind::Underflow => "number too small to fit in target type",
+ IntErrorKind::Zero => "number would be zero for non-zero type",
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseIntError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.__description().fmt(f)
+ }
+}
diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs
index 9bf56e9..e8f9d65 100644
--- a/library/core/src/num/flt2dec/mod.rs
+++ b/library/core/src/num/flt2dec/mod.rs
@@ -124,6 +124,8 @@
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
+use crate::mem::MaybeUninit;
+
pub mod decoder;
pub mod estimator;
@@ -140,23 +142,23 @@
/// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`.
pub const MAX_SIG_DIGITS: usize = 17;
-/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry.
-/// Returns a next digit when it causes the length change.
+/// When `d` contains decimal digits, increase the last digit and propagate carry.
+/// Returns a next digit when it causes the length to change.
#[doc(hidden)]
-pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> {
- match d[..n].iter().rposition(|&c| c != b'9') {
+pub fn round_up(d: &mut [u8]) -> Option<u8> {
+ match d.iter().rposition(|&c| c != b'9') {
Some(i) => {
// d[i+1..n] is all nines
d[i] += 1;
- for j in i + 1..n {
+ for j in i + 1..d.len() {
d[j] = b'0';
}
None
}
- None if n > 0 => {
+ None if d.len() > 0 => {
// 999..999 rounds to 1000..000 with an increased exponent
d[0] = b'1';
- for j in 1..n {
+ for j in 1..d.len() {
d[j] = b'0';
}
Some(b'0')
@@ -281,7 +283,7 @@
buf: &'a [u8],
exp: i16,
frac_digits: usize,
- parts: &'a mut [Part<'a>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> &'a [Part<'a>] {
assert!(!buf.is_empty());
assert!(buf[0] > b'0');
@@ -303,38 +305,44 @@
if exp <= 0 {
// the decimal point is before rendered digits: [0.][000...000][1234][____]
let minus_exp = -(exp as i32) as usize;
- parts[0] = Part::Copy(b"0.");
- parts[1] = Part::Zero(minus_exp);
- parts[2] = Part::Copy(buf);
+ parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+ parts[1] = MaybeUninit::new(Part::Zero(minus_exp));
+ parts[2] = MaybeUninit::new(Part::Copy(buf));
if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp {
- parts[3] = Part::Zero((frac_digits - buf.len()) - minus_exp);
- &parts[..4]
+ parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp));
+ // SAFETY: we just initialized the elements `..4`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
- &parts[..3]
+ // SAFETY: we just initialized the elements `..3`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
}
} else {
let exp = exp as usize;
if exp < buf.len() {
// the decimal point is inside rendered digits: [12][.][34][____]
- parts[0] = Part::Copy(&buf[..exp]);
- parts[1] = Part::Copy(b".");
- parts[2] = Part::Copy(&buf[exp..]);
+ parts[0] = MaybeUninit::new(Part::Copy(&buf[..exp]));
+ parts[1] = MaybeUninit::new(Part::Copy(b"."));
+ parts[2] = MaybeUninit::new(Part::Copy(&buf[exp..]));
if frac_digits > buf.len() - exp {
- parts[3] = Part::Zero(frac_digits - (buf.len() - exp));
- &parts[..4]
+ parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp)));
+ // SAFETY: we just initialized the elements `..4`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
- &parts[..3]
+ // SAFETY: we just initialized the elements `..3`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
}
} else {
// the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].
- parts[0] = Part::Copy(buf);
- parts[1] = Part::Zero(exp - buf.len());
+ parts[0] = MaybeUninit::new(Part::Copy(buf));
+ parts[1] = MaybeUninit::new(Part::Zero(exp - buf.len()));
if frac_digits > 0 {
- parts[2] = Part::Copy(b".");
- parts[3] = Part::Zero(frac_digits);
- &parts[..4]
+ parts[2] = MaybeUninit::new(Part::Copy(b"."));
+ parts[3] = MaybeUninit::new(Part::Zero(frac_digits));
+ // SAFETY: we just initialized the elements `..4`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
} else {
- &parts[..2]
+ // SAFETY: we just initialized the elements `..2`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }
}
}
}
@@ -354,7 +362,7 @@
exp: i16,
min_ndigits: usize,
upper: bool,
- parts: &'a mut [Part<'a>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> &'a [Part<'a>] {
assert!(!buf.is_empty());
assert!(buf[0] > b'0');
@@ -362,15 +370,15 @@
let mut n = 0;
- parts[n] = Part::Copy(&buf[..1]);
+ parts[n] = MaybeUninit::new(Part::Copy(&buf[..1]));
n += 1;
if buf.len() > 1 || min_ndigits > 1 {
- parts[n] = Part::Copy(b".");
- parts[n + 1] = Part::Copy(&buf[1..]);
+ parts[n] = MaybeUninit::new(Part::Copy(b"."));
+ parts[n + 1] = MaybeUninit::new(Part::Copy(&buf[1..]));
n += 2;
if min_ndigits > buf.len() {
- parts[n] = Part::Zero(min_ndigits - buf.len());
+ parts[n] = MaybeUninit::new(Part::Zero(min_ndigits - buf.len()));
n += 1;
}
}
@@ -378,13 +386,14 @@
// 0.1234 x 10^exp = 1.234 x 10^(exp-1)
let exp = exp as i32 - 1; // avoid underflow when exp is i16::MIN
if exp < 0 {
- parts[n] = Part::Copy(if upper { b"E-" } else { b"e-" });
- parts[n + 1] = Part::Num(-exp as u16);
+ parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E-" } else { b"e-" }));
+ parts[n + 1] = MaybeUninit::new(Part::Num(-exp as u16));
} else {
- parts[n] = Part::Copy(if upper { b"E" } else { b"e" });
- parts[n + 1] = Part::Num(exp as u16);
+ parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E" } else { b"e" }));
+ parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16));
}
- &parts[..n + 2]
+ // SAFETY: we just initialized the elements `..n + 2`.
+ unsafe { MaybeUninit::slice_assume_init_ref(&parts[..n + 2]) }
}
/// Sign formatting options.
@@ -446,6 +455,7 @@
/// (which can be an empty string if no sign is rendered).
///
/// `format_shortest` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
/// You probably would want `strategy::grisu::format_shortest` for this.
///
/// `frac_digits` can be less than the number of actual fractional digits in `v`;
@@ -461,12 +471,12 @@
v: T,
sign: Sign,
frac_digits: usize,
- buf: &'a mut [u8],
- parts: &'a mut [Part<'a>],
+ buf: &'a mut [MaybeUninit<u8>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> Formatted<'a>
where
T: DecodableFloat,
- F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+ F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
{
assert!(parts.len() >= 4);
assert!(buf.len() >= MAX_SIG_DIGITS);
@@ -475,27 +485,37 @@
let sign = determine_sign(sign, &full_decoded, negative);
match full_decoded {
FullDecoded::Nan => {
- parts[0] = Part::Copy(b"NaN");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
- parts[0] = Part::Copy(b"inf");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if frac_digits > 0 {
// [0.][0000]
- parts[0] = Part::Copy(b"0.");
- parts[1] = Part::Zero(frac_digits);
- Formatted { sign, parts: &parts[..2] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+ parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..2`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
+ }
} else {
- parts[0] = Part::Copy(b"0");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..1`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
+ }
}
}
FullDecoded::Finite(ref decoded) => {
- let (len, exp) = format_shortest(decoded, buf);
- Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+ let (buf, exp) = format_shortest(decoded, buf);
+ Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) }
}
}
}
@@ -509,6 +529,7 @@
/// an empty string if no sign is rendered).
///
/// `format_shortest` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
/// You probably would want `strategy::grisu::format_shortest` for this.
///
/// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted
@@ -525,12 +546,12 @@
sign: Sign,
dec_bounds: (i16, i16),
upper: bool,
- buf: &'a mut [u8],
- parts: &'a mut [Part<'a>],
+ buf: &'a mut [MaybeUninit<u8>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> Formatted<'a>
where
T: DecodableFloat,
- F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+ F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
{
assert!(parts.len() >= 6);
assert!(buf.len() >= MAX_SIG_DIGITS);
@@ -540,28 +561,31 @@
let sign = determine_sign(sign, &full_decoded, negative);
match full_decoded {
FullDecoded::Nan => {
- parts[0] = Part::Copy(b"NaN");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
- parts[0] = Part::Copy(b"inf");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 {
- Part::Copy(b"0")
+ MaybeUninit::new(Part::Copy(b"0"))
} else {
- Part::Copy(if upper { b"0E0" } else { b"0e0" })
+ MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }))
};
- Formatted { sign, parts: &parts[..1] }
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Finite(ref decoded) => {
- let (len, exp) = format_shortest(decoded, buf);
+ let (buf, exp) = format_shortest(decoded, buf);
let vis_exp = exp as i32 - 1;
let parts = if dec_bounds.0 as i32 <= vis_exp && vis_exp < dec_bounds.1 as i32 {
- digits_to_dec_str(&buf[..len], exp, 0, parts)
+ digits_to_dec_str(buf, exp, 0, parts)
} else {
- digits_to_exp_str(&buf[..len], exp, 0, upper, parts)
+ digits_to_exp_str(buf, exp, 0, upper, parts)
};
Formatted { sign, parts }
}
@@ -600,6 +624,7 @@
/// an empty string if no sign is rendered).
///
/// `format_exact` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
/// You probably would want `strategy::grisu::format_exact` for this.
///
/// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is
@@ -613,12 +638,12 @@
sign: Sign,
ndigits: usize,
upper: bool,
- buf: &'a mut [u8],
- parts: &'a mut [Part<'a>],
+ buf: &'a mut [MaybeUninit<u8>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> Formatted<'a>
where
T: DecodableFloat,
- F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+ F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
assert!(parts.len() >= 6);
assert!(ndigits > 0);
@@ -627,23 +652,33 @@
let sign = determine_sign(sign, &full_decoded, negative);
match full_decoded {
FullDecoded::Nan => {
- parts[0] = Part::Copy(b"NaN");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
- parts[0] = Part::Copy(b"inf");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if ndigits > 1 {
// [0.][0000][e0]
- parts[0] = Part::Copy(b"0.");
- parts[1] = Part::Zero(ndigits - 1);
- parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" });
- Formatted { sign, parts: &parts[..3] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+ parts[1] = MaybeUninit::new(Part::Zero(ndigits - 1));
+ parts[2] = MaybeUninit::new(Part::Copy(if upper { b"E0" } else { b"e0" }));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..3`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) },
+ }
} else {
- parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" });
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..1`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
+ }
}
}
FullDecoded::Finite(ref decoded) => {
@@ -651,8 +686,8 @@
assert!(buf.len() >= ndigits || buf.len() >= maxlen);
let trunc = if ndigits < maxlen { ndigits } else { maxlen };
- let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
- Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
+ let (buf, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
+ Formatted { sign, parts: digits_to_exp_str(buf, exp, ndigits, upper, parts) }
}
}
}
@@ -665,6 +700,7 @@
/// (which can be an empty string if no sign is rendered).
///
/// `format_exact` should be the underlying digit-generation function.
+/// It should return the part of the buffer that it initialized.
/// You probably would want `strategy::grisu::format_exact` for this.
///
/// The byte buffer should be enough for the output unless `frac_digits` is
@@ -677,12 +713,12 @@
v: T,
sign: Sign,
frac_digits: usize,
- buf: &'a mut [u8],
- parts: &'a mut [Part<'a>],
+ buf: &'a mut [MaybeUninit<u8>],
+ parts: &'a mut [MaybeUninit<Part<'a>>],
) -> Formatted<'a>
where
T: DecodableFloat,
- F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
+ F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
assert!(parts.len() >= 4);
@@ -690,22 +726,32 @@
let sign = determine_sign(sign, &full_decoded, negative);
match full_decoded {
FullDecoded::Nan => {
- parts[0] = Part::Copy(b"NaN");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Infinite => {
- parts[0] = Part::Copy(b"inf");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
+ // SAFETY: we just initialized the elements `..1`.
+ Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
}
FullDecoded::Zero => {
if frac_digits > 0 {
// [0.][0000]
- parts[0] = Part::Copy(b"0.");
- parts[1] = Part::Zero(frac_digits);
- Formatted { sign, parts: &parts[..2] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+ parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..2`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
+ }
} else {
- parts[0] = Part::Copy(b"0");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..1`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
+ }
}
}
FullDecoded::Finite(ref decoded) => {
@@ -716,23 +762,31 @@
// `format_exact` will end rendering digits much earlier in this case,
// because we are strictly limited by `maxlen`.
let limit = if frac_digits < 0x8000 { -(frac_digits as i16) } else { i16::MIN };
- let (len, exp) = format_exact(decoded, &mut buf[..maxlen], limit);
+ let (buf, exp) = format_exact(decoded, &mut buf[..maxlen], limit);
if exp <= limit {
// the restriction couldn't been met, so this should render like zero no matter
// `exp` was. this does not include the case that the restriction has been met
// only after the final rounding-up; it's a regular case with `exp = limit + 1`.
- debug_assert_eq!(len, 0);
+ debug_assert_eq!(buf.len(), 0);
if frac_digits > 0 {
// [0.][0000]
- parts[0] = Part::Copy(b"0.");
- parts[1] = Part::Zero(frac_digits);
- Formatted { sign, parts: &parts[..2] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0."));
+ parts[1] = MaybeUninit::new(Part::Zero(frac_digits));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..2`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
+ }
} else {
- parts[0] = Part::Copy(b"0");
- Formatted { sign, parts: &parts[..1] }
+ parts[0] = MaybeUninit::new(Part::Copy(b"0"));
+ Formatted {
+ sign,
+ // SAFETY: we just initialized the elements `..1`.
+ parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
+ }
}
} else {
- Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
+ Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) }
}
}
}
diff --git a/library/core/src/num/flt2dec/strategy/dragon.rs b/library/core/src/num/flt2dec/strategy/dragon.rs
index c8de000..8ced597 100644
--- a/library/core/src/num/flt2dec/strategy/dragon.rs
+++ b/library/core/src/num/flt2dec/strategy/dragon.rs
@@ -5,6 +5,7 @@
//! quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
use crate::cmp::Ordering;
+use crate::mem::MaybeUninit;
use crate::num::bignum::Big32x40 as Big;
use crate::num::bignum::Digit32 as Digit;
@@ -97,7 +98,10 @@
}
/// The shortest mode implementation for Dragon.
-pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_shortest<'a>(
+ d: &Decoded,
+ buf: &'a mut [MaybeUninit<u8>],
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
// the number `v` to format is known to be:
// - equal to `mant * 2^exp`;
// - preceded by `(mant - 2 * minus) * 2^exp` in the original type; and
@@ -186,7 +190,7 @@
// generate one digit: `d[n] = floor(mant / scale) < 10`.
let (d, _) = div_rem_upto_16(&mut mant, &scale, &scale2, &scale4, &scale8);
debug_assert!(d < 10);
- buf[i] = b'0' + d;
+ buf[i] = MaybeUninit::new(b'0' + d);
i += 1;
// this is a simplified description of the modified Dragon algorithm.
@@ -241,18 +245,24 @@
// if rounding up changes the length, the exponent should also change.
// it seems that this condition is very hard to satisfy (possibly impossible),
// but we are just being safe and consistent here.
- if let Some(c) = round_up(buf, i) {
- buf[i] = c;
+ // SAFETY: we initialized that memory above.
+ if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }) {
+ buf[i] = MaybeUninit::new(c);
i += 1;
k += 1;
}
}
- (i, k)
+ // SAFETY: we initialized that memory above.
+ (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..i]) }, k)
}
/// The exact and fixed mode implementation for Dragon.
-pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_exact<'a>(
+ d: &Decoded,
+ buf: &'a mut [MaybeUninit<u8>],
+ limit: i16,
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
assert!(d.mant > 0);
assert!(d.minus > 0);
assert!(d.plus > 0);
@@ -319,9 +329,10 @@
// following digits are all zeroes, we stop here
// do *not* try to perform rounding! rather, fill remaining digits.
for c in &mut buf[i..len] {
- *c = b'0';
+ *c = MaybeUninit::new(b'0');
}
- return (len, k);
+ // SAFETY: we initialized that memory above.
+ return (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k);
}
let mut d = 0;
@@ -343,7 +354,7 @@
}
debug_assert!(mant < scale);
debug_assert!(d < 10);
- buf[i] = b'0' + d;
+ buf[i] = MaybeUninit::new(b'0' + d);
mant.mul_small(10);
}
}
@@ -353,21 +364,25 @@
// round to even (i.e., avoid rounding up when the prior digit is even).
let order = mant.cmp(scale.mul_small(5));
if order == Ordering::Greater
- || (order == Ordering::Equal && (len == 0 || buf[len - 1] & 1 == 1))
+ || (order == Ordering::Equal
+ // SAFETY: `buf[len-1]` is initialized.
+ && (len == 0 || unsafe { buf[len - 1].assume_init() } & 1 == 1))
{
// if rounding up changes the length, the exponent should also change.
// but we've been requested a fixed number of digits, so do not alter the buffer...
- if let Some(c) = round_up(buf, len) {
+ // SAFETY: we initialized that memory above.
+ if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) }) {
// ...unless we've been requested the fixed precision instead.
// we also need to check that, if the original buffer was empty,
// the additional digit can only be added when `k == limit` (edge case).
k += 1;
if k > limit && len < buf.len() {
- buf[len] = c;
+ buf[len] = MaybeUninit::new(c);
len += 1;
}
}
}
- (len, k)
+ // SAFETY: we initialized that memory above.
+ (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k)
}
diff --git a/library/core/src/num/flt2dec/strategy/grisu.rs b/library/core/src/num/flt2dec/strategy/grisu.rs
index 1e2db21..a4cb51c 100644
--- a/library/core/src/num/flt2dec/strategy/grisu.rs
+++ b/library/core/src/num/flt2dec/strategy/grisu.rs
@@ -5,6 +5,7 @@
//! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and
//! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
+use crate::mem::MaybeUninit;
use crate::num::diy_float::Fp;
use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
@@ -161,10 +162,10 @@
/// The shortest mode implementation for Grisu.
///
/// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_shortest_opt(
+pub fn format_shortest_opt<'a>(
d: &Decoded,
- buf: &mut [u8],
-) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+ buf: &'a mut [MaybeUninit<u8>],
+) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> {
assert!(d.mant > 0);
assert!(d.minus > 0);
assert!(d.plus > 0);
@@ -266,14 +267,23 @@
let q = remainder / ten_kappa;
let r = remainder % ten_kappa;
debug_assert!(q < 10);
- buf[i] = b'0' + q as u8;
+ buf[i] = MaybeUninit::new(b'0' + q as u8);
i += 1;
let plus1rem = ((r as u64) << e) + plus1frac; // == (plus1 % 10^kappa) * 2^e
if plus1rem < delta1 {
// `plus1 % 10^kappa < delta1 = plus1 - minus1`; we've found the correct `kappa`.
let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent
- return round_and_weed(&mut buf[..i], exp, plus1rem, delta1, plus1 - v.f, ten_kappa, 1);
+ return round_and_weed(
+ // SAFETY: we initialized that memory above.
+ unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
+ exp,
+ plus1rem,
+ delta1,
+ plus1 - v.f,
+ ten_kappa,
+ 1,
+ );
}
// break the loop when we have rendered all integral digits.
@@ -310,13 +320,14 @@
let q = remainder >> e;
let r = remainder & ((1 << e) - 1);
debug_assert!(q < 10);
- buf[i] = b'0' + q as u8;
+ buf[i] = MaybeUninit::new(b'0' + q as u8);
i += 1;
if r < threshold {
let ten_kappa = 1 << e; // implicit divisor
return round_and_weed(
- &mut buf[..i],
+ // SAFETY: we initialized that memory above.
+ unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
exp,
r,
threshold,
@@ -355,7 +366,7 @@
plus1v: u64,
ten_kappa: u64,
ulp: u64,
- ) -> Option<(usize, i16)> {
+ ) -> Option<(&[u8], i16)> {
assert!(!buf.is_empty());
// produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps.
@@ -437,20 +448,22 @@
// this is too liberal, though, so we reject any `w(n)` not between `plus0` and `minus0`,
// i.e., `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts
// that `threshold = plus1 - minus1` and `plus1 - plus0 = minus0 - minus1 = 2 ulp`.
- if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp {
- Some((buf.len(), exp))
- } else {
- None
- }
+ if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp { Some((buf, exp)) } else { None }
}
}
/// The shortest mode implementation for Grisu with Dragon fallback.
///
/// This should be used for most cases.
-pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_shortest<'a>(
+ d: &Decoded,
+ buf: &'a mut [MaybeUninit<u8>],
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
use crate::num::flt2dec::strategy::dragon::format_shortest as fallback;
- match format_shortest_opt(d, buf) {
+ // SAFETY: The borrow checker is not smart enough to let us use `buf`
+ // in the second branch, so we launder the lifetime here. But we only re-use
+ // `buf` if `format_shortest_opt` returned `None` so this is okay.
+ match format_shortest_opt(d, unsafe { &mut *(buf as *mut _) }) {
Some(ret) => ret,
None => fallback(d, buf),
}
@@ -459,11 +472,11 @@
/// The exact and fixed mode implementation for Grisu.
///
/// It returns `None` when it would return an inexact representation otherwise.
-pub fn format_exact_opt(
+pub fn format_exact_opt<'a>(
d: &Decoded,
- buf: &mut [u8],
+ buf: &'a mut [MaybeUninit<u8>],
limit: i16,
-) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
+) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> {
assert!(d.mant > 0);
assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision
assert!(!buf.is_empty());
@@ -510,7 +523,11 @@
// thus we are being sloppy here and widen the error range by a factor of 10.
// this will increase the false negative rate, but only very, *very* slightly;
// it can only matter noticeably when the mantissa is bigger than 60 bits.
- return possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e);
+ //
+ // SAFETY: `len=0`, so the obligation of having initialized this memory is trivial.
+ return unsafe {
+ possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e)
+ };
} else if ((exp as i32 - limit as i32) as usize) < buf.len() {
(exp - limit) as usize
} else {
@@ -534,13 +551,16 @@
let q = remainder / ten_kappa;
let r = remainder % ten_kappa;
debug_assert!(q < 10);
- buf[i] = b'0' + q as u8;
+ buf[i] = MaybeUninit::new(b'0' + q as u8);
i += 1;
// is the buffer full? run the rounding pass with the remainder.
if i == len {
let vrem = ((r as u64) << e) + vfrac; // == (v % 10^kappa) * 2^e
- return possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e);
+ // SAFETY: we have initialized `len` many bytes.
+ return unsafe {
+ possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e)
+ };
}
// break the loop when we have rendered all integral digits.
@@ -585,12 +605,13 @@
let q = remainder >> e;
let r = remainder & ((1 << e) - 1);
debug_assert!(q < 10);
- buf[i] = b'0' + q as u8;
+ buf[i] = MaybeUninit::new(b'0' + q as u8);
i += 1;
// is the buffer full? run the rounding pass with the remainder.
if i == len {
- return possibly_round(buf, len, exp, limit, r, 1 << e, err);
+ // SAFETY: we have initialized `len` many bytes.
+ return unsafe { possibly_round(buf, len, exp, limit, r, 1 << e, err) };
}
// restore invariants
@@ -610,15 +631,17 @@
// - `remainder = (v % 10^kappa) * k`
// - `ten_kappa = 10^kappa * k`
// - `ulp = 2^-e * k`
- fn possibly_round(
- buf: &mut [u8],
+ //
+ // SAFETY: the first `len` bytes of `buf` must be initialized.
+ unsafe fn possibly_round(
+ buf: &mut [MaybeUninit<u8>],
mut len: usize,
mut exp: i16,
limit: i16,
remainder: u64,
ten_kappa: u64,
ulp: u64,
- ) -> Option<(usize, i16)> {
+ ) -> Option<(&[u8], i16)> {
debug_assert!(remainder < ten_kappa);
// 10^kappa
@@ -677,7 +700,8 @@
// we've already verified that `ulp < 10^kappa / 2`, so as long as
// `10^kappa` did not overflow after all, the second check is fine.
if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp {
- return Some((len, exp));
+ // SAFETY: our caller initialized that memory.
+ return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
}
// :<------- remainder ------>| :
@@ -698,17 +722,21 @@
// as `10^kappa` is never zero). also note that `remainder - ulp <= 10^kappa`,
// so the second check does not overflow.
if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp {
- if let Some(c) = round_up(buf, len) {
+ if let Some(c) =
+ // SAFETY: our caller must have initialized that memory.
+ round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) })
+ {
// only add an additional digit when we've been requested the fixed precision.
// we also need to check that, if the original buffer was empty,
// the additional digit can only be added when `exp == limit` (edge case).
exp += 1;
if exp > limit && len < buf.len() {
- buf[len] = c;
+ buf[len] = MaybeUninit::new(c);
len += 1;
}
}
- return Some((len, exp));
+ // SAFETY: we and our caller initialized that memory.
+ return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
}
// otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are
@@ -720,9 +748,16 @@
/// The exact and fixed mode implementation for Grisu with Dragon fallback.
///
/// This should be used for most cases.
-pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) {
+pub fn format_exact<'a>(
+ d: &Decoded,
+ buf: &'a mut [MaybeUninit<u8>],
+ limit: i16,
+) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
use crate::num::flt2dec::strategy::dragon::format_exact as fallback;
- match format_exact_opt(d, buf, limit) {
+ // SAFETY: The borrow checker is not smart enough to let us use `buf`
+ // in the second branch, so we launder the lifetime here. But we only re-use
+ // `buf` if `format_exact_opt` returned `None` so this is okay.
+ match format_exact_opt(d, unsafe { &mut *(buf as *mut _) }, limit) {
Some(ret) => ret,
None => fallback(d, buf, limit),
}
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index ffd30b0..369175f 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1,49 +1,2201 @@
-#![doc(hidden)]
-
-macro_rules! doc_comment {
- ($x:expr, $($tt:tt)*) => {
- #[doc = $x]
- $($tt)*
- };
-}
-
-macro_rules! int_module {
- ($T:ident) => (int_module!($T, #[stable(feature = "rust1", since = "1.0.0")]););
- ($T:ident, #[$attr:meta]) => (
+macro_rules! int_impl {
+ ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
+ $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
+ $reversed:expr, $le_bytes:expr, $be_bytes:expr,
+ $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
doc_comment! {
concat!("The smallest value that can be represented by this integer type.
-Use [`", stringify!($T), "::MIN", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MIN) instead.
# Examples
-```rust
-// deprecated way
-let min = std::", stringify!($T), "::MIN;
+Basic usage:
-// intended way
-let min = ", stringify!($T), "::MIN;
```
-"),
- #[$attr]
- pub const MIN: $T = $T::MIN;
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+ pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self;
}
doc_comment! {
concat!("The largest value that can be represented by this integer type.
-Use [`", stringify!($T), "::MAX", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MAX) instead.
# Examples
-```rust
-// deprecated way
-let max = std::", stringify!($T), "::MAX;
+Basic usage:
-// intended way
-let max = ", stringify!($T), "::MAX;
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+ pub const MAX: Self = !Self::MIN;
+ }
+
+ doc_comment! {
+ concat!("The size of this integer type in bits.
+
+# Examples
+
+```
+", $Feature, "#![feature(int_bits_const)]
+assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");",
+$EndFeature, "
+```"),
+ #[unstable(feature = "int_bits_const", issue = "76904")]
+ pub const BITS: u32 = $BITS;
+ }
+
+ doc_comment! {
+ concat!("Converts a string slice in a given base to an integer.
+
+The string is expected to be an optional `+` or `-` sign followed by digits.
+Leading and trailing whitespace represent an error. Digits are a subset of these characters,
+depending on `radix`:
+
+ * `0-9`
+ * `a-z`
+ * `A-Z`
+
+# Panics
+
+This function panics if `radix` is not in the range from 2 to 36.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
+ from_str_radix(src, radix)
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b100_0000", stringify!($SelfT), ";
+
+assert_eq!(n.count_ones(), 1);",
+$EndFeature, "
```
"),
- #[$attr]
- pub const MAX: $T = $T::MAX;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
}
- )
+
+ doc_comment! {
+ concat!("Returns the number of zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 1);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn count_zeros(self) -> u32 {
+ (!self).count_ones()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of leading zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = -1", stringify!($SelfT), ";
+
+assert_eq!(n.leading_zeros(), 0);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn leading_zeros(self) -> u32 {
+ (self as $UnsignedT).leading_zeros()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of trailing zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = -4", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_zeros(), 2);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn trailing_zeros(self) -> u32 {
+ (self as $UnsignedT).trailing_zeros()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of leading ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = -1", stringify!($SelfT), ";
+
+assert_eq!(n.leading_ones(), ", stringify!($BITS), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[inline]
+ pub const fn leading_ones(self) -> u32 {
+ (self as $UnsignedT).leading_ones()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of trailing ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 3", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_ones(), 2);",
+$EndFeature, "
+```"),
+ #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[inline]
+ pub const fn trailing_ones(self) -> u32 {
+ (self as $UnsignedT).trailing_ones()
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts the bits to the left by a specified amount, `n`,
+wrapping the truncated bits to the end of the resulting integer.
+
+Please note this isn't the same operation as the `<<` shifting operator!
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $rot_op, stringify!($SelfT), ";
+let m = ", $rot_result, ";
+
+assert_eq!(n.rotate_left(", $rot, "), m);
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn rotate_left(self, n: u32) -> Self {
+ (self as $UnsignedT).rotate_left(n) as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts the bits to the right by a specified amount, `n`,
+wrapping the truncated bits to the beginning of the resulting
+integer.
+
+Please note this isn't the same operation as the `>>` shifting operator!
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $rot_result, stringify!($SelfT), ";
+let m = ", $rot_op, ";
+
+assert_eq!(n.rotate_right(", $rot, "), m);
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn rotate_right(self, n: u32) -> Self {
+ (self as $UnsignedT).rotate_right(n) as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Reverses the byte order of the integer.
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $swap_op, stringify!($SelfT), ";
+
+let m = n.swap_bytes();
+
+assert_eq!(m, ", $swapped, ");
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn swap_bytes(self) -> Self {
+ (self as $UnsignedT).swap_bytes() as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Reverses the bit pattern of the integer.
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $swap_op, stringify!($SelfT), ";
+let m = n.reverse_bits();
+
+assert_eq!(m, ", $reversed, ");
+```"),
+ #[stable(feature = "reverse_bits", since = "1.37.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ #[must_use]
+ pub const fn reverse_bits(self) -> Self {
+ (self as $UnsignedT).reverse_bits() as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from big endian to the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+ #[inline]
+ pub const fn from_be(x: Self) -> Self {
+ #[cfg(target_endian = "big")]
+ {
+ x
+ }
+ #[cfg(not(target_endian = "big"))]
+ {
+ x.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from little endian to the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+ #[inline]
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ x.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to big endian from the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(n.to_be(), n)
+} else {
+ assert_eq!(n.to_be(), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+ #[inline]
+ pub const fn to_be(self) -> Self { // or not to be?
+ #[cfg(target_endian = "big")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "big"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to little endian from the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(n.to_le(), n)
+} else {
+ assert_eq!(n.to_le(), n.swap_bytes())
+}",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+ #[inline]
+ pub const fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer addition. Computes `self + rhs`, returning `None`
+if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::MAX - 2).checked_add(1), Some(", stringify!($SelfT), "::MAX - 1));
+assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT),
+"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_add`.
+ unsafe { intrinsics::unchecked_add(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer subtraction. Computes `self - rhs`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::MIN + 2).checked_sub(1), Some(", stringify!($SelfT), "::MIN + 1));
+assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub(3), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_sub(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT),
+"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_sub`.
+ unsafe { intrinsics::unchecked_sub(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer multiplication. Computes `self * rhs`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT),
+"::MAX.checked_mul(1), Some(", stringify!($SelfT), "::MAX));
+assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_mul(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT),
+"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_mul`.
+ unsafe { intrinsics::unchecked_mul(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
+or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT),
+"::MIN + 1).checked_div(-1), Some(", stringify!($Max), "));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_div(-1), None);
+assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_div(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
+ None
+ } else {
+ // SAFETY: div by zero and by INT_MIN have been checked above
+ Some(unsafe { intrinsics::unchecked_div(self, rhs) })
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`,
+returning `None` if `rhs == 0` or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!((", stringify!($SelfT),
+"::MIN + 1).checked_div_euclid(-1), Some(", stringify!($Max), "));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_div_euclid(-1), None);
+assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
+ None
+ } else {
+ Some(self.div_euclid(rhs))
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if
+`rhs == 0` or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);
+assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
+ None
+ } else {
+ // SAFETY: div by zero and by INT_MIN have been checked above
+ Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
+if `rhs == 0` or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
+assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
+ None
+ } else {
+ Some(self.rem_euclid(rhs))
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked negation. Computes `-self`, returning `None` if `self == MIN`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".checked_neg(), Some(-5));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn checked_neg(self) -> Option<Self> {
+ let (a, b) = self.overflowing_neg();
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
+than or equal to the number of bits in `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
+assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shl(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
+larger than or equal to the number of bits in `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shr(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked absolute value. Computes `self.abs()`, returning `None` if
+`self == MIN`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!((-5", stringify!($SelfT), ").checked_abs(), Some(5));
+assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn checked_abs(self) -> Option<Self> {
+ if self.is_negative() {
+ self.checked_neg()
+ } else {
+ Some(self)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64));
+assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);",
+$EndFeature, "
+```"),
+
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ if exp == 0 {
+ return Some(1);
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = try_opt!(acc.checked_mul(base));
+ }
+ exp /= 2;
+ base = try_opt!(base.checked_mul(base));
+ }
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ Some(try_opt!(acc.checked_mul(base)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
+bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(100), ", stringify!($SelfT),
+"::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_add(-1), ", stringify!($SelfT),
+"::MIN);",
+$EndFeature, "
+```"),
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_add(self, rhs: Self) -> Self {
+ intrinsics::saturating_add(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
+numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_sub(100), ", stringify!($SelfT),
+"::MIN);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_sub(-1), ", stringify!($SelfT),
+"::MAX);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_sub(self, rhs: Self) -> Self {
+ intrinsics::saturating_sub(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
+instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
+assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_neg(), ", stringify!($SelfT),
+"::MAX);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_neg(), ", stringify!($SelfT),
+"::MIN + 1);",
+$EndFeature, "
+```"),
+
+ #[stable(feature = "saturating_neg", since = "1.45.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn saturating_neg(self) -> Self {
+ intrinsics::saturating_sub(0, self)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self ==
+MIN` instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
+assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_abs(), ", stringify!($SelfT),
+"::MAX);
+assert_eq!((", stringify!($SelfT), "::MIN + 1).saturating_abs(), ", stringify!($SelfT),
+"::MAX);",
+$EndFeature, "
+```"),
+
+ #[stable(feature = "saturating_neg", since = "1.45.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn saturating_abs(self) -> Self {
+ if self.is_negative() {
+ self.saturating_neg()
+ } else {
+ self
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the
+numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(10", stringify!($SelfT), ".saturating_mul(12), 120);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_mul(10), ", stringify!($SelfT), "::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($SelfT), "::MIN);",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_mul(self, rhs: Self) -> Self {
+ match self.checked_mul(rhs) {
+ Some(x) => x,
+ None => if (self < 0) == (rhs < 0) {
+ Self::MAX
+ } else {
+ Self::MIN
+ }
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_pow(self, exp: u32) -> Self {
+ match self.checked_pow(exp) {
+ Some(x) => x,
+ None if self < 0 && exp % 2 == 1 => Self::MIN,
+ None => Self::MAX,
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
+boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_add(27), 127);
+assert_eq!(", stringify!($SelfT), "::MAX.wrapping_add(2), ", stringify!($SelfT),
+"::MIN + 1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_add(self, rhs: Self) -> Self {
+ intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
+boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0", stringify!($SelfT), ".wrapping_sub(127), -127);
+assert_eq!((-2", stringify!($SelfT), ").wrapping_sub(", stringify!($SelfT), "::MAX), ",
+stringify!($SelfT), "::MAX);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_sub(self, rhs: Self) -> Self {
+ intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at
+the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".wrapping_mul(12), 120);
+assert_eq!(11i8.wrapping_mul(12), -124);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_mul(self, rhs: Self) -> Self {
+ intrinsics::wrapping_mul(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) division. Computes `self / rhs`, wrapping around at the
+boundary of the type.
+
+The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where
+`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value
+that is too large to represent in the type. In such a case, this function returns `MIN` itself.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);
+assert_eq!((-128i8).wrapping_div(-1), -128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_div(self, rhs: Self) -> Self {
+ self.overflowing_div(rhs).0
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`,
+wrapping around at the boundary of the type.
+
+Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is the negative minimal value
+for the type). This is equivalent to `-MIN`, a positive value that is too large to represent in the
+type. In this case, this method returns `MIN` itself.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
+assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
+ self.overflowing_div_euclid(rhs).0
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the
+boundary of the type.
+
+Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y`
+invalid for `MIN / -1` on a signed type (where `MIN` is the negative minimal value). In such a case,
+this function returns `0`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);
+assert_eq!((-128i8).wrapping_rem(-1), 0);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_rem(self, rhs: Self) -> Self {
+ self.overflowing_rem(rhs).0
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping around
+at the boundary of the type.
+
+Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is the negative minimal value
+for the type). In this case, this method returns 0.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
+assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
+ self.overflowing_rem_euclid(rhs).0
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
+of the type.
+
+The only case where such wrapping can occur is when one negates `MIN` on a signed type (where `MIN`
+is the negative minimal value for the type); this is a positive value that is too large to represent
+in the type. In such a case, this function returns `MIN` itself.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);
+assert_eq!(", stringify!($SelfT), "::MIN.wrapping_neg(), ", stringify!($SelfT),
+"::MIN);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn wrapping_neg(self) -> Self {
+ self.overflowing_neg().0
+ }
+ }
+
+ doc_comment! {
+ concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
+any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
+the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
+The primitive integer types all implement a `[`rotate_left`](#method.rotate_left) function,
+which may be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);
+assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_shl(self, rhs: u32) -> Self {
+ // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+ // out of bounds
+ unsafe {
+ intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask`
+removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
+to the range of the type, rather than the bits shifted out of the LHS being returned to the other
+end. The primitive integer types all implement a [`rotate_right`](#method.rotate_right) function,
+which may be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);
+assert_eq!((-128i16).wrapping_shr(64), -128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_shr(self, rhs: u32) -> Self {
+ // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+ // out of bounds
+ unsafe {
+ intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) absolute value. Computes `self.abs()`, wrapping around at
+the boundary of the type.
+
+The only case where such wrapping can occur is when one takes the absolute value of the negative
+minimal value for the type; this is a positive value that is too large to represent in the type. In
+such a case, this function returns `MIN` itself.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_abs(), 100);
+assert_eq!((-100", stringify!($SelfT), ").wrapping_abs(), 100);
+assert_eq!(", stringify!($SelfT), "::MIN.wrapping_abs(), ", stringify!($SelfT),
+"::MIN);
+assert_eq!((-128i8).wrapping_abs() as u8, 128);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[allow(unused_attributes)]
+ #[inline]
+ pub const fn wrapping_abs(self) -> Self {
+ if self.is_negative() {
+ self.wrapping_neg()
+ } else {
+ self
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Computes the absolute value of `self` without any wrapping
+or panicking.
+
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(unsigned_abs)]
+assert_eq!(100", stringify!($SelfT), ".unsigned_abs(), 100", stringify!($UnsignedT), ");
+assert_eq!((-100", stringify!($SelfT), ").unsigned_abs(), 100", stringify!($UnsignedT), ");
+assert_eq!((-128i8).unsigned_abs(), 128u8);",
+$EndFeature, "
+```"),
+ #[unstable(feature = "unsigned_abs", issue = "74913")]
+ #[inline]
+ pub const fn unsigned_abs(self) -> $UnsignedT {
+ self.wrapping_abs() as $UnsignedT
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81);
+assert_eq!(3i8.wrapping_pow(5), -13);
+assert_eq!(3i8.wrapping_pow(6), -39);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
+ if exp == 0 {
+ return 1;
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.wrapping_mul(base);
+ }
+ exp /= 2;
+ base = base.wrapping_mul(base);
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ acc.wrapping_mul(base)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates `self` + `rhs`
+
+Returns a tuple of the addition along with a boolean indicating whether an arithmetic overflow would
+occur. If an overflow would have occurred then the wrapped value is returned.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
+assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($SelfT),
+"::MIN, true));", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates `self` - `rhs`
+
+Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow
+would occur. If an overflow would have occurred then the wrapped value is returned.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($SelfT),
+"::MAX, true));", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the multiplication of `self` and `rhs`.
+
+Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic overflow
+would occur. If an overflow would have occurred then the wrapped value is returned.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mul(2), (10, false));
+assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the divisor when `self` is divided by `rhs`.
+
+Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would
+occur. If an overflow would occur then self is returned.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div(-1), (", stringify!($SelfT),
+"::MIN, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
+ if unlikely!(self == Self::MIN && rhs == -1) {
+ (self, true)
+ } else {
+ (self / rhs, false)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
+
+Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would
+occur. If an overflow would occur then `self` is returned.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringify!($SelfT),
+"::MIN, true));
+```"),
+ #[inline]
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
+ if unlikely!(self == Self::MIN && rhs == -1) {
+ (self, true)
+ } else {
+ (self.div_euclid(rhs), false)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the remainder when `self` is divided by `rhs`.
+
+Returns a tuple of the remainder after dividing along with a boolean indicating whether an
+arithmetic overflow would occur. If an overflow would occur then 0 is returned.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem(-1), (0, true));",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
+ if unlikely!(self == Self::MIN && rhs == -1) {
+ (0, true)
+ } else {
+ (self % rhs, false)
+ }
+ }
+ }
+
+
+ doc_comment! {
+ concat!("Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`.
+
+Returns a tuple of the remainder after dividing along with a boolean indicating whether an
+arithmetic overflow would occur. If an overflow would occur then 0 is returned.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
+ if unlikely!(self == Self::MIN && rhs == -1) {
+ (0, true)
+ } else {
+ (self.rem_euclid(rhs), false)
+ }
+ }
+ }
+
+
+ doc_comment! {
+ concat!("Negates self, overflowing if this is equal to the minimum value.
+
+Returns a tuple of the negated version of self along with a boolean indicating whether an overflow
+happened. If `self` is the minimum value (e.g., `i32::MIN` for values of type `i32`), then the
+minimum value will be returned again and `true` will be returned for an overflow happening.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2, false));
+assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($SelfT),
+"::MIN, true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[allow(unused_attributes)]
+ pub const fn overflowing_neg(self) -> (Self, bool) {
+ if unlikely!(self == Self::MIN) {
+ (Self::MIN, true)
+ } else {
+ (-self, false)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts self left by `rhs` bits.
+
+Returns a tuple of the shifted version of self along with a boolean indicating whether the shift
+value was larger than or equal to the number of bits. If the shift value is too large, then value is
+masked (N-1) where N is the number of bits, and this value is then used to perform the shift.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x1", stringify!($SelfT),".overflowing_shl(4), (0x10, false));
+assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts self right by `rhs` bits.
+
+Returns a tuple of the shifted version of self along with a boolean indicating whether the shift
+value was larger than or equal to the number of bits. If the shift value is too large, then value is
+masked (N-1) where N is the number of bits, and this value is then used to perform the shift.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
+assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Computes the absolute value of `self`.
+
+Returns a tuple of the absolute version of self along with a boolean indicating whether an overflow
+happened. If self is the minimum value (e.g., ", stringify!($SelfT), "::MIN for values of type
+ ", stringify!($SelfT), "), then the minimum value will be returned again and true will be returned
+for an overflow happening.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".overflowing_abs(), (10, false));
+assert_eq!((-10", stringify!($SelfT), ").overflowing_abs(), (10, false));
+assert_eq!((", stringify!($SelfT), "::MIN).overflowing_abs(), (", stringify!($SelfT),
+"::MIN, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_abs", since = "1.13.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn overflowing_abs(self) -> (Self, bool) {
+ (self.wrapping_abs(), self == Self::MIN)
+ }
+ }
+
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false));
+assert_eq!(3i8.overflowing_pow(5), (-13, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ if exp == 0 {
+ return (1,false);
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+ let mut overflown = false;
+ // Scratch space for storing results of overflowing_mul.
+ let mut r;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+ exp /= 2;
+ r = base.overflowing_mul(base);
+ base = r.0;
+ overflown |= r.1;
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ r = acc.overflowing_mul(base);
+ r.1 |= overflown;
+ r
+ }
+ }
+
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let x: ", stringify!($SelfT), " = 2; // or any other integer type
+
+assert_eq!(x.pow(5), 32);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn pow(self, mut exp: u32) -> Self {
+ if exp == 0 {
+ return 1;
+ }
+ let mut base = self;
+ let mut acc = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc * base;
+ }
+ exp /= 2;
+ base = base * base;
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ acc * base
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the quotient of Euclidean division of `self` by `rhs`.
+
+This computes the integer `n` such that `self = n * rhs + self.rem_euclid(rhs)`,
+with `0 <= self.rem_euclid(rhs) < rhs`.
+
+In other words, the result is `self / rhs` rounded to the integer `n`
+such that `self >= n * rhs`.
+If `self > 0`, this is equal to round towards zero (the default in Rust);
+if `self < 0`, this is equal to round towards +/- infinity.
+
+# Panics
+
+This function will panic if `rhs` is 0 or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+let a: ", stringify!($SelfT), " = 7; // or any other integer type
+let b = 4;
+
+assert_eq!(a.div_euclid(b), 1); // 7 >= 4 * 1
+assert_eq!(a.div_euclid(-b), -1); // 7 >= -4 * -1
+assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2
+assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn div_euclid(self, rhs: Self) -> Self {
+ let q = self / rhs;
+ if self % rhs < 0 {
+ return if rhs > 0 { q - 1 } else { q + 1 }
+ }
+ q
+ }
+ }
+
+
+ doc_comment! {
+ concat!("Calculates the least nonnegative remainder of `self (mod rhs)`.
+
+This is done as if by the Euclidean division algorithm -- given
+`r = self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
+`0 <= r < abs(rhs)`.
+
+# Panics
+
+This function will panic if `rhs` is 0 or the division results in overflow.
+
+# Examples
+
+Basic usage:
+
+```
+let a: ", stringify!($SelfT), " = 7; // or any other integer type
+let b = 4;
+
+assert_eq!(a.rem_euclid(b), 3);
+assert_eq!((-a).rem_euclid(b), 1);
+assert_eq!(a.rem_euclid(-b), 3);
+assert_eq!((-a).rem_euclid(-b), 1);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn rem_euclid(self, rhs: Self) -> Self {
+ let r = self % rhs;
+ if r < 0 {
+ if rhs < 0 {
+ r - rhs
+ } else {
+ r + rhs
+ }
+ } else {
+ r
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Computes the absolute value of `self`.
+
+# Overflow behavior
+
+The absolute value of `", stringify!($SelfT), "::MIN` cannot be represented as an
+`", stringify!($SelfT), "`, and attempting to calculate it will cause an overflow. This means that
+code in debug mode will trigger a panic on this case and optimized code will return `",
+stringify!($SelfT), "::MIN` without a panic.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".abs(), 10);
+assert_eq!((-10", stringify!($SelfT), ").abs(), 10);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[allow(unused_attributes)]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn abs(self) -> Self {
+ // Note that the #[inline] above means that the overflow
+ // semantics of the subtraction depend on the crate we're being
+ // inlined into.
+ if self.is_negative() {
+ -self
+ } else {
+ self
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns a number representing sign of `self`.
+
+ - `0` if the number is zero
+ - `1` if the number is positive
+ - `-1` if the number is negative
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(10", stringify!($SelfT), ".signum(), 1);
+assert_eq!(0", stringify!($SelfT), ".signum(), 0);
+assert_eq!((-10", stringify!($SelfT), ").signum(), -1);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_sign", since = "1.47.0")]
+ #[inline]
+ pub const fn signum(self) -> Self {
+ match self {
+ n if n > 0 => 1,
+ 0 => 0,
+ _ => -1,
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns `true` if `self` is positive and `false` if the number is zero or
+negative.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!(10", stringify!($SelfT), ".is_positive());
+assert!(!(-10", stringify!($SelfT), ").is_positive());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn is_positive(self) -> bool { self > 0 }
+ }
+
+ doc_comment! {
+ concat!("Returns `true` if `self` is negative and `false` if the number is zero or
+positive.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!((-10", stringify!($SelfT), ").is_negative());
+assert!(!10", stringify!($SelfT), ".is_negative());",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+ #[inline]
+ pub const fn is_negative(self) -> bool { self < 0 }
+ }
+
+ doc_comment! {
+ concat!("Return the memory representation of this integer as a byte array in
+big-endian (network) byte order.
+",
+$to_xe_bytes_doc,
+"
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
+assert_eq!(bytes, ", $be_bytes, ");
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ self.to_be().to_ne_bytes()
+ }
+ }
+
+doc_comment! {
+ concat!("Return the memory representation of this integer as a byte array in
+little-endian byte order.
+",
+$to_xe_bytes_doc,
+"
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
+assert_eq!(bytes, ", $le_bytes, ");
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ self.to_le().to_ne_bytes()
+ }
+ }
+
+ doc_comment! {
+ concat!("
+Return the memory representation of this integer as a byte array in
+native byte order.
+
+As the target platform's native endianness is used, portable code
+should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
+instead.
+",
+$to_xe_bytes_doc,
+"
+[`to_be_bytes`]: #method.to_be_bytes
+[`to_le_bytes`]: #method.to_le_bytes
+
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
+assert_eq!(
+ bytes,
+ if cfg!(target_endian = \"big\") {
+ ", $be_bytes, "
+ } else {
+ ", $le_bytes, "
+ }
+);
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ // SAFETY: const sound because integers are plain old datatypes so we can always
+ // transmute them to arrays of bytes
+ #[allow_internal_unstable(const_fn_transmute)]
+ #[inline]
+ pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ // SAFETY: integers are plain old datatypes so we can always transmute them to
+ // arrays of bytes
+ unsafe { mem::transmute(self) }
+ }
+ }
+
+doc_comment! {
+ concat!("Create an integer value from its representation as a byte array in
+big endian.
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_be(Self::from_ne_bytes(bytes))
+ }
+ }
+
+doc_comment! {
+ concat!("
+Create an integer value from its representation as a byte array in
+little endian.
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+ }
+
+ doc_comment! {
+ concat!("Create an integer value from its memory representation as a byte
+array in native endianness.
+
+As the target platform's native endianness is used, portable code
+likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
+appropriate instead.
+
+[`from_be_bytes`]: #method.from_be_bytes
+[`from_le_bytes`]: #method.from_le_bytes
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
+ ", $be_bytes, "
+} else {
+ ", $le_bytes, "
+});
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ // SAFETY: const sound because integers are plain old datatypes so we can always
+ // transmute to them
+ #[allow_internal_unstable(const_fn_transmute)]
+ #[inline]
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ // SAFETY: integers are plain old datatypes so we can always transmute to them
+ unsafe { mem::transmute(bytes) }
+ }
+ }
+
+ doc_comment! {
+ concat!("**This method is soft-deprecated.**
+
+Although using it won’t cause a compilation warning,
+new code should use [`", stringify!($SelfT), "::MIN", "`](#associatedconstant.MIN) instead.
+
+Returns the smallest value that can be represented by this integer type."),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline(always)]
+ #[rustc_promotable]
+ #[rustc_const_stable(feature = "const_min_value", since = "1.32.0")]
+ pub const fn min_value() -> Self {
+ Self::MIN
+ }
+ }
+
+ doc_comment! {
+ concat!("**This method is soft-deprecated.**
+
+Although using it won’t cause a compilation warning,
+new code should use [`", stringify!($SelfT), "::MAX", "`](#associatedconstant.MAX) instead.
+
+Returns the largest value that can be represented by this integer type."),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline(always)]
+ #[rustc_promotable]
+ #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
+ pub const fn max_value() -> Self {
+ Self::MAX
+ }
+ }
+ }
}
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 7a88cfb..4f64e30 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -1,14 +1,9 @@
-// ignore-tidy-filelength
-
//! Numeric traits and functions for the built-in numeric types.
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::convert::Infallible;
-use crate::fmt;
use crate::intrinsics;
use crate::mem;
-use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;
// Used because the `?` operator is not allowed in a const context.
@@ -28,20 +23,6 @@
};
}
-macro_rules! impl_nonzero_fmt {
- ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
- $(
- #[$stability]
- impl fmt::$Trait for $Ty {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.get().fmt(f)
- }
- }
- )+
- }
-}
-
macro_rules! doc_comment {
($x:expr, $($tt:tt)*) => {
#[doc = $x]
@@ -49,248 +30,42 @@
};
}
-macro_rules! nonzero_integers {
- ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
- $(
- doc_comment! {
- concat!("An integer that is known not to equal zero.
-
-This enables some memory layout optimization.
-For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:
-
-```rust
-use std::mem::size_of;
-assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
-">());
-```"),
- #[$stability]
- #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
- #[repr(transparent)]
- #[rustc_layout_scalar_valid_range_start(1)]
- #[rustc_nonnull_optimization_guaranteed]
- pub struct $Ty($Int);
- }
-
- impl $Ty {
- /// Creates a non-zero without checking the value.
- ///
- /// # Safety
- ///
- /// The value must not be zero.
- #[$stability]
- #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
- #[inline]
- pub const unsafe fn new_unchecked(n: $Int) -> Self {
- // SAFETY: this is guaranteed to be safe by the caller.
- unsafe { Self(n) }
- }
-
- /// Creates a non-zero if the given value is not zero.
- #[$stability]
- #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn new(n: $Int) -> Option<Self> {
- if n != 0 {
- // SAFETY: we just checked that there's no `0`
- Some(unsafe { Self(n) })
- } else {
- None
- }
- }
-
- /// Returns the value as a primitive type.
- #[$stability]
- #[inline]
- #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
- pub const fn get(self) -> $Int {
- self.0
- }
-
- }
-
- #[stable(feature = "from_nonzero", since = "1.31.0")]
- impl From<$Ty> for $Int {
- doc_comment! {
- concat!(
-"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
- fn from(nonzero: $Ty) -> Self {
- nonzero.0
- }
- }
- }
-
- #[stable(feature = "nonzero_bitor", since = "1.45.0")]
- impl BitOr for $Ty {
- type Output = Self;
- #[inline]
- fn bitor(self, rhs: Self) -> Self::Output {
- // Safety: since `self` and `rhs` are both nonzero, the
- // result of the bitwise-or will be nonzero.
- unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
- }
- }
-
- #[stable(feature = "nonzero_bitor", since = "1.45.0")]
- impl BitOr<$Int> for $Ty {
- type Output = Self;
- #[inline]
- fn bitor(self, rhs: $Int) -> Self::Output {
- // Safety: since `self` is nonzero, the result of the
- // bitwise-or will be nonzero regardless of the value of
- // `rhs`.
- unsafe { $Ty::new_unchecked(self.get() | rhs) }
- }
- }
-
- #[stable(feature = "nonzero_bitor", since = "1.45.0")]
- impl BitOr<$Ty> for $Int {
- type Output = $Ty;
- #[inline]
- fn bitor(self, rhs: $Ty) -> Self::Output {
- // Safety: since `rhs` is nonzero, the result of the
- // bitwise-or will be nonzero regardless of the value of
- // `self`.
- unsafe { $Ty::new_unchecked(self | rhs.get()) }
- }
- }
-
- #[stable(feature = "nonzero_bitor", since = "1.45.0")]
- impl BitOrAssign for $Ty {
- #[inline]
- fn bitor_assign(&mut self, rhs: Self) {
- *self = *self | rhs;
- }
- }
-
- #[stable(feature = "nonzero_bitor", since = "1.45.0")]
- impl BitOrAssign<$Int> for $Ty {
- #[inline]
- fn bitor_assign(&mut self, rhs: $Int) {
- *self = *self | rhs;
- }
- }
-
- impl_nonzero_fmt! {
- #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
- }
- )+
- }
-}
-
-nonzero_integers! {
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
- #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
- #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
-}
-
-macro_rules! from_str_radix_nzint_impl {
- ($($t:ty)*) => {$(
- #[stable(feature = "nonzero_parse", since = "1.35.0")]
- impl FromStr for $t {
- type Err = ParseIntError;
- fn from_str(src: &str) -> Result<Self, Self::Err> {
- Self::new(from_str_radix(src, 10)?)
- .ok_or(ParseIntError {
- kind: IntErrorKind::Zero
- })
- }
- }
- )*}
-}
-
-from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
-NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
-
-/// Provides intentionally-wrapped arithmetic on `T`.
-///
-/// Operations like `+` on `u32` values are intended to never overflow,
-/// and in some debug configurations overflow is detected and results
-/// in a panic. While most arithmetic falls into this category, some
-/// code explicitly expects and relies upon modular arithmetic (e.g.,
-/// hashing).
-///
-/// Wrapping arithmetic can be achieved either through methods like
-/// `wrapping_add`, or through the `Wrapping<T>` type, which says that
-/// all standard arithmetic operations on the underlying value are
-/// intended to have wrapping semantics.
-///
-/// The underlying value can be retrieved through the `.0` index of the
-/// `Wrapping` tuple.
-///
-/// # Examples
-///
-/// ```
-/// use std::num::Wrapping;
-///
-/// let zero = Wrapping(0u32);
-/// let one = Wrapping(1u32);
-///
-/// assert_eq!(u32::MAX, (zero - one).0);
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
-#[repr(transparent)]
-pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug> fmt::Debug for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[stable(feature = "wrapping_display", since = "1.10.0")]
-impl<T: fmt::Display> fmt::Display for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[stable(feature = "wrapping_fmt", since = "1.11.0")]
-impl<T: fmt::Binary> fmt::Binary for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[stable(feature = "wrapping_fmt", since = "1.11.0")]
-impl<T: fmt::Octal> fmt::Octal for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[stable(feature = "wrapping_fmt", since = "1.11.0")]
-impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[stable(feature = "wrapping_fmt", since = "1.11.0")]
-impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
// All these modules are technically private and only exposed for coretests:
pub mod bignum;
pub mod dec2flt;
pub mod diy_float;
pub mod flt2dec;
+#[macro_use]
+mod int_macros; // import int_impl!
+#[macro_use]
+mod uint_macros; // import uint_impl!
+
+mod error;
+mod nonzero;
mod wrapping;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use wrapping::Wrapping;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use dec2flt::ParseFloatError;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use error::ParseIntError;
+
+#[stable(feature = "nonzero", since = "1.28.0")]
+pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
+
+#[stable(feature = "signed_nonzero", since = "1.34.0")]
+pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
+
+#[stable(feature = "try_from", since = "1.34.0")]
+pub use error::TryFromIntError;
+
+#[unstable(feature = "int_error_matching", issue = "22639")]
+pub use error::IntErrorKind;
+
macro_rules! usize_isize_to_xe_bytes_doc {
() => {
"
@@ -313,2194 +88,6 @@
};
}
-macro_rules! int_impl {
- ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
- $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
- $reversed:expr, $le_bytes:expr, $be_bytes:expr,
- $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
- doc_comment! {
- concat!("The smallest value that can be represented by this integer type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");",
-$EndFeature, "
-```"),
- #[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self;
- }
-
- doc_comment! {
- concat!("The largest value that can be represented by this integer type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");",
-$EndFeature, "
-```"),
- #[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MAX: Self = !Self::MIN;
- }
-
- doc_comment! {
- concat!("Converts a string slice in a given base to an integer.
-
-The string is expected to be an optional `+` or `-` sign followed by digits.
-Leading and trailing whitespace represent an error. Digits are a subset of these characters,
-depending on `radix`:
-
- * `0-9`
- * `a-z`
- * `A-Z`
-
-# Panics
-
-This function panics if `radix` is not in the range from 2 to 36.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
- from_str_radix(src, radix)
- }
- }
-
- doc_comment! {
- concat!("Returns the number of ones in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0b100_0000", stringify!($SelfT), ";
-
-assert_eq!(n.count_ones(), 1);",
-$EndFeature, "
-```
-"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
- }
-
- doc_comment! {
- concat!("Returns the number of zeros in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 1);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn count_zeros(self) -> u32 {
- (!self).count_ones()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of leading zeros in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = -1", stringify!($SelfT), ";
-
-assert_eq!(n.leading_zeros(), 0);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn leading_zeros(self) -> u32 {
- (self as $UnsignedT).leading_zeros()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of trailing zeros in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = -4", stringify!($SelfT), ";
-
-assert_eq!(n.trailing_zeros(), 2);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn trailing_zeros(self) -> u32 {
- (self as $UnsignedT).trailing_zeros()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of leading ones in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = -1", stringify!($SelfT), ";
-
-assert_eq!(n.leading_ones(), ", stringify!($BITS), ");",
-$EndFeature, "
-```"),
- #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[inline]
- pub const fn leading_ones(self) -> u32 {
- (self as $UnsignedT).leading_ones()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of trailing ones in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 3", stringify!($SelfT), ";
-
-assert_eq!(n.trailing_ones(), 2);",
-$EndFeature, "
-```"),
- #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[inline]
- pub const fn trailing_ones(self) -> u32 {
- (self as $UnsignedT).trailing_ones()
- }
- }
-
- doc_comment! {
- concat!("Shifts the bits to the left by a specified amount, `n`,
-wrapping the truncated bits to the end of the resulting integer.
-
-Please note this isn't the same operation as the `<<` shifting operator!
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $rot_op, stringify!($SelfT), ";
-let m = ", $rot_result, ";
-
-assert_eq!(n.rotate_left(", $rot, "), m);
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn rotate_left(self, n: u32) -> Self {
- (self as $UnsignedT).rotate_left(n) as Self
- }
- }
-
- doc_comment! {
- concat!("Shifts the bits to the right by a specified amount, `n`,
-wrapping the truncated bits to the beginning of the resulting
-integer.
-
-Please note this isn't the same operation as the `>>` shifting operator!
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $rot_result, stringify!($SelfT), ";
-let m = ", $rot_op, ";
-
-assert_eq!(n.rotate_right(", $rot, "), m);
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn rotate_right(self, n: u32) -> Self {
- (self as $UnsignedT).rotate_right(n) as Self
- }
- }
-
- doc_comment! {
- concat!("Reverses the byte order of the integer.
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $swap_op, stringify!($SelfT), ";
-
-let m = n.swap_bytes();
-
-assert_eq!(m, ", $swapped, ");
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn swap_bytes(self) -> Self {
- (self as $UnsignedT).swap_bytes() as Self
- }
- }
-
- doc_comment! {
- concat!("Reverses the bit pattern of the integer.
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $swap_op, stringify!($SelfT), ";
-let m = n.reverse_bits();
-
-assert_eq!(m, ", $reversed, ");
-```"),
- #[stable(feature = "reverse_bits", since = "1.37.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- #[must_use]
- pub const fn reverse_bits(self) -> Self {
- (self as $UnsignedT).reverse_bits() as Self
- }
- }
-
- doc_comment! {
- concat!("Converts an integer from big endian to the target's endianness.
-
-On big endian this is a no-op. On little endian the bytes are swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"big\") {
- assert_eq!(", stringify!($SelfT), "::from_be(n), n)
-} else {
- assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
-}",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
- #[inline]
- pub const fn from_be(x: Self) -> Self {
- #[cfg(target_endian = "big")]
- {
- x
- }
- #[cfg(not(target_endian = "big"))]
- {
- x.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts an integer from little endian to the target's endianness.
-
-On little endian this is a no-op. On big endian the bytes are swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"little\") {
- assert_eq!(", stringify!($SelfT), "::from_le(n), n)
-} else {
- assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
-}",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
- #[inline]
- pub const fn from_le(x: Self) -> Self {
- #[cfg(target_endian = "little")]
- {
- x
- }
- #[cfg(not(target_endian = "little"))]
- {
- x.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts `self` to big endian from the target's endianness.
-
-On big endian this is a no-op. On little endian the bytes are swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"big\") {
- assert_eq!(n.to_be(), n)
-} else {
- assert_eq!(n.to_be(), n.swap_bytes())
-}",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
- #[inline]
- pub const fn to_be(self) -> Self { // or not to be?
- #[cfg(target_endian = "big")]
- {
- self
- }
- #[cfg(not(target_endian = "big"))]
- {
- self.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts `self` to little endian from the target's endianness.
-
-On little endian this is a no-op. On big endian the bytes are swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"little\") {
- assert_eq!(n.to_le(), n)
-} else {
- assert_eq!(n.to_le(), n.swap_bytes())
-}",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
- #[inline]
- pub const fn to_le(self) -> Self {
- #[cfg(target_endian = "little")]
- {
- self
- }
- #[cfg(not(target_endian = "little"))]
- {
- self.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Checked integer addition. Computes `self + rhs`, returning `None`
-if overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((", stringify!($SelfT),
-"::MAX - 2).checked_add(1), Some(", stringify!($SelfT), "::MAX - 1));
-assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_add(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT),
-"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_add`.
- unsafe { intrinsics::unchecked_add(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer subtraction. Computes `self - rhs`, returning `None` if
-overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((", stringify!($SelfT),
-"::MIN + 2).checked_sub(1), Some(", stringify!($SelfT), "::MIN + 1));
-assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub(3), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_sub(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT),
-"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_sub`.
- unsafe { intrinsics::unchecked_sub(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer multiplication. Computes `self * rhs`, returning `None` if
-overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT),
-"::MAX.checked_mul(1), Some(", stringify!($SelfT), "::MAX));
-assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_mul(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT),
-"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_mul`.
- unsafe { intrinsics::unchecked_mul(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
-or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((", stringify!($SelfT),
-"::MIN + 1).checked_div(-1), Some(", stringify!($Max), "));
-assert_eq!(", stringify!($SelfT), "::MIN.checked_div(-1), None);
-assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_div(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
- None
- } else {
- // SAFETY: div by zero and by INT_MIN have been checked above
- Some(unsafe { intrinsics::unchecked_div(self, rhs) })
- }
- }
- }
-
- doc_comment! {
- concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`,
-returning `None` if `rhs == 0` or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!((", stringify!($SelfT),
-"::MIN + 1).checked_div_euclid(-1), Some(", stringify!($Max), "));
-assert_eq!(", stringify!($SelfT), "::MIN.checked_div_euclid(-1), None);
-assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
- None
- } else {
- Some(self.div_euclid(rhs))
- }
- }
- }
-
- doc_comment! {
- concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if
-`rhs == 0` or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
-assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);
-assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
- None
- } else {
- // SAFETY: div by zero and by INT_MIN have been checked above
- Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
- }
- }
- }
-
- doc_comment! {
- concat!("Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
-if `rhs == 0` or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
-assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
-assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) {
- None
- } else {
- Some(self.rem_euclid(rhs))
- }
- }
- }
-
- doc_comment! {
- concat!("Checked negation. Computes `-self`, returning `None` if `self == MIN`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".checked_neg(), Some(-5));
-assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn checked_neg(self) -> Option<Self> {
- let (a, b) = self.overflowing_neg();
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
-than or equal to the number of bits in `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
-assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shl(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
-larger than or equal to the number of bits in `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
-assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shr(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked absolute value. Computes `self.abs()`, returning `None` if
-`self == MIN`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!((-5", stringify!($SelfT), ").checked_abs(), Some(5));
-assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn checked_abs(self) -> Option<Self> {
- if self.is_negative() {
- self.checked_neg()
- } else {
- Some(self)
- }
- }
- }
-
- doc_comment! {
- concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
-overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64));
-assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);",
-$EndFeature, "
-```"),
-
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
- if exp == 0 {
- return Some(1);
- }
- let mut base = self;
- let mut acc: Self = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = try_opt!(acc.checked_mul(base));
- }
- exp /= 2;
- base = try_opt!(base.checked_mul(base));
- }
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- Some(try_opt!(acc.checked_mul(base)))
- }
- }
-
- doc_comment! {
- concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
-bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(100), ", stringify!($SelfT),
-"::MAX);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_add(-1), ", stringify!($SelfT),
-"::MIN);",
-$EndFeature, "
-```"),
-
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_add(self, rhs: Self) -> Self {
- intrinsics::saturating_add(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
-numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_sub(100), ", stringify!($SelfT),
-"::MIN);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_sub(-1), ", stringify!($SelfT),
-"::MAX);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_sub(self, rhs: Self) -> Self {
- intrinsics::saturating_sub(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
-instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
-assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_neg(), ", stringify!($SelfT),
-"::MAX);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_neg(), ", stringify!($SelfT),
-"::MIN + 1);",
-$EndFeature, "
-```"),
-
- #[stable(feature = "saturating_neg", since = "1.45.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn saturating_neg(self) -> Self {
- intrinsics::saturating_sub(0, self)
- }
- }
-
- doc_comment! {
- concat!("Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self ==
-MIN` instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
-assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_abs(), ", stringify!($SelfT),
-"::MAX);
-assert_eq!((", stringify!($SelfT), "::MIN + 1).saturating_abs(), ", stringify!($SelfT),
-"::MAX);",
-$EndFeature, "
-```"),
-
- #[stable(feature = "saturating_neg", since = "1.45.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn saturating_abs(self) -> Self {
- if self.is_negative() {
- self.saturating_neg()
- } else {
- self
- }
- }
- }
-
- doc_comment! {
- concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the
-numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(10", stringify!($SelfT), ".saturating_mul(12), 120);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_mul(10), ", stringify!($SelfT), "::MAX);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($SelfT), "::MIN);",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_mul(self, rhs: Self) -> Self {
- match self.checked_mul(rhs) {
- Some(x) => x,
- None => if (self < 0) == (rhs < 0) {
- Self::MAX
- } else {
- Self::MIN
- }
- }
- }
- }
-
- doc_comment! {
- concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
-saturating at the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX);
-assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_pow(self, exp: u32) -> Self {
- match self.checked_pow(exp) {
- Some(x) => x,
- None if self < 0 && exp % 2 == 1 => Self::MIN,
- None => Self::MAX,
- }
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
-boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_add(27), 127);
-assert_eq!(", stringify!($SelfT), "::MAX.wrapping_add(2), ", stringify!($SelfT),
-"::MIN + 1);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_add(self, rhs: Self) -> Self {
- intrinsics::wrapping_add(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
-boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0", stringify!($SelfT), ".wrapping_sub(127), -127);
-assert_eq!((-2", stringify!($SelfT), ").wrapping_sub(", stringify!($SelfT), "::MAX), ",
-stringify!($SelfT), "::MAX);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_sub(self, rhs: Self) -> Self {
- intrinsics::wrapping_sub(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at
-the boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(10", stringify!($SelfT), ".wrapping_mul(12), 120);
-assert_eq!(11i8.wrapping_mul(12), -124);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_mul(self, rhs: Self) -> Self {
- intrinsics::wrapping_mul(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) division. Computes `self / rhs`, wrapping around at the
-boundary of the type.
-
-The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where
-`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value
-that is too large to represent in the type. In such a case, this function returns `MIN` itself.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);
-assert_eq!((-128i8).wrapping_div(-1), -128);",
-$EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_div(self, rhs: Self) -> Self {
- self.overflowing_div(rhs).0
- }
- }
-
- doc_comment! {
- concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`,
-wrapping around at the boundary of the type.
-
-Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is the negative minimal value
-for the type). This is equivalent to `-MIN`, a positive value that is too large to represent in the
-type. In this case, this method returns `MIN` itself.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
-assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
- self.overflowing_div_euclid(rhs).0
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the
-boundary of the type.
-
-Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y`
-invalid for `MIN / -1` on a signed type (where `MIN` is the negative minimal value). In such a case,
-this function returns `0`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);
-assert_eq!((-128i8).wrapping_rem(-1), 0);",
-$EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_rem(self, rhs: Self) -> Self {
- self.overflowing_rem(rhs).0
- }
- }
-
- doc_comment! {
- concat!("Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping around
-at the boundary of the type.
-
-Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is the negative minimal value
-for the type). In this case, this method returns 0.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
-assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
- self.overflowing_rem_euclid(rhs).0
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
-of the type.
-
-The only case where such wrapping can occur is when one negates `MIN` on a signed type (where `MIN`
-is the negative minimal value for the type); this is a positive value that is too large to represent
-in the type. In such a case, this function returns `MIN` itself.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);
-assert_eq!(", stringify!($SelfT), "::MIN.wrapping_neg(), ", stringify!($SelfT),
-"::MIN);",
-$EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn wrapping_neg(self) -> Self {
- self.overflowing_neg().0
- }
- }
-
- doc_comment! {
- concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
-any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
-
-Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
-the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
-The primitive integer types all implement a `[`rotate_left`](#method.rotate_left) function,
-which may be what you want instead.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);
-assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);",
-$EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_shl(self, rhs: u32) -> Self {
- // SAFETY: the masking by the bitsize of the type ensures that we do not shift
- // out of bounds
- unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
- }
- }
- }
-
- doc_comment! {
- concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask`
-removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
-
-Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
-to the range of the type, rather than the bits shifted out of the LHS being returned to the other
-end. The primitive integer types all implement a [`rotate_right`](#method.rotate_right) function,
-which may be what you want instead.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);
-assert_eq!((-128i16).wrapping_shr(64), -128);",
-$EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_shr(self, rhs: u32) -> Self {
- // SAFETY: the masking by the bitsize of the type ensures that we do not shift
- // out of bounds
- unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
- }
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) absolute value. Computes `self.abs()`, wrapping around at
-the boundary of the type.
-
-The only case where such wrapping can occur is when one takes the absolute value of the negative
-minimal value for the type; this is a positive value that is too large to represent in the type. In
-such a case, this function returns `MIN` itself.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_abs(), 100);
-assert_eq!((-100", stringify!($SelfT), ").wrapping_abs(), 100);
-assert_eq!(", stringify!($SelfT), "::MIN.wrapping_abs(), ", stringify!($SelfT),
-"::MIN);
-assert_eq!((-128i8).wrapping_abs() as u8, 128);",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[allow(unused_attributes)]
- #[inline]
- pub const fn wrapping_abs(self) -> Self {
- if self.is_negative() {
- self.wrapping_neg()
- } else {
- self
- }
- }
- }
-
- doc_comment! {
- concat!("Computes the absolute value of `self` without any wrapping
-or panicking.
-
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "#![feature(unsigned_abs)]
-assert_eq!(100", stringify!($SelfT), ".unsigned_abs(), 100", stringify!($UnsignedT), ");
-assert_eq!((-100", stringify!($SelfT), ").unsigned_abs(), 100", stringify!($UnsignedT), ");
-assert_eq!((-128i8).unsigned_abs(), 128u8);",
-$EndFeature, "
-```"),
- #[unstable(feature = "unsigned_abs", issue = "74913")]
- #[inline]
- pub const fn unsigned_abs(self) -> $UnsignedT {
- self.wrapping_abs() as $UnsignedT
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
-wrapping around at the boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81);
-assert_eq!(3i8.wrapping_pow(5), -13);
-assert_eq!(3i8.wrapping_pow(6), -39);",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_pow(self, mut exp: u32) -> Self {
- if exp == 0 {
- return 1;
- }
- let mut base = self;
- let mut acc: Self = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = acc.wrapping_mul(base);
- }
- exp /= 2;
- base = base.wrapping_mul(base);
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- acc.wrapping_mul(base)
- }
- }
-
- doc_comment! {
- concat!("Calculates `self` + `rhs`
-
-Returns a tuple of the addition along with a boolean indicating whether an arithmetic overflow would
-occur. If an overflow would have occurred then the wrapped value is returned.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
-assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($SelfT),
-"::MIN, true));", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
- }
-
- doc_comment! {
- concat!("Calculates `self` - `rhs`
-
-Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow
-would occur. If an overflow would have occurred then the wrapped value is returned.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($SelfT),
-"::MAX, true));", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
- }
-
- doc_comment! {
- concat!("Calculates the multiplication of `self` and `rhs`.
-
-Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic overflow
-would occur. If an overflow would have occurred then the wrapped value is returned.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mul(2), (10, false));
-assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
- }
-
- doc_comment! {
- concat!("Calculates the divisor when `self` is divided by `rhs`.
-
-Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would
-occur. If an overflow would occur then self is returned.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div(-1), (", stringify!($SelfT),
-"::MIN, true));",
-$EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
- if unlikely!(self == Self::MIN && rhs == -1) {
- (self, true)
- } else {
- (self / rhs, false)
- }
- }
- }
-
- doc_comment! {
- concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
-
-Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would
-occur. If an overflow would occur then `self` is returned.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringify!($SelfT),
-"::MIN, true));
-```"),
- #[inline]
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
- if unlikely!(self == Self::MIN && rhs == -1) {
- (self, true)
- } else {
- (self.div_euclid(rhs), false)
- }
- }
- }
-
- doc_comment! {
- concat!("Calculates the remainder when `self` is divided by `rhs`.
-
-Returns a tuple of the remainder after dividing along with a boolean indicating whether an
-arithmetic overflow would occur. If an overflow would occur then 0 is returned.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem(-1), (0, true));",
-$EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
- if unlikely!(self == Self::MIN && rhs == -1) {
- (0, true)
- } else {
- (self % rhs, false)
- }
- }
- }
-
-
- doc_comment! {
- concat!("Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`.
-
-Returns a tuple of the remainder after dividing along with a boolean indicating whether an
-arithmetic overflow would occur. If an overflow would occur then 0 is returned.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
- if unlikely!(self == Self::MIN && rhs == -1) {
- (0, true)
- } else {
- (self.rem_euclid(rhs), false)
- }
- }
- }
-
-
- doc_comment! {
- concat!("Negates self, overflowing if this is equal to the minimum value.
-
-Returns a tuple of the negated version of self along with a boolean indicating whether an overflow
-happened. If `self` is the minimum value (e.g., `i32::MIN` for values of type `i32`), then the
-minimum value will be returned again and `true` will be returned for an overflow happening.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2, false));
-assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($SelfT),
-"::MIN, true));", $EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[allow(unused_attributes)]
- pub const fn overflowing_neg(self) -> (Self, bool) {
- if unlikely!(self == Self::MIN) {
- (Self::MIN, true)
- } else {
- (-self, false)
- }
- }
- }
-
- doc_comment! {
- concat!("Shifts self left by `rhs` bits.
-
-Returns a tuple of the shifted version of self along with a boolean indicating whether the shift
-value was larger than or equal to the number of bits. If the shift value is too large, then value is
-masked (N-1) where N is the number of bits, and this value is then used to perform the shift.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x1", stringify!($SelfT),".overflowing_shl(4), (0x10, false));
-assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
- }
- }
-
- doc_comment! {
- concat!("Shifts self right by `rhs` bits.
-
-Returns a tuple of the shifted version of self along with a boolean indicating whether the shift
-value was larger than or equal to the number of bits. If the shift value is too large, then value is
-masked (N-1) where N is the number of bits, and this value is then used to perform the shift.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
-assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
- }
- }
-
- doc_comment! {
- concat!("Computes the absolute value of `self`.
-
-Returns a tuple of the absolute version of self along with a boolean indicating whether an overflow
-happened. If self is the minimum value (e.g., ", stringify!($SelfT), "::MIN for values of type
- ", stringify!($SelfT), "), then the minimum value will be returned again and true will be returned
-for an overflow happening.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(10", stringify!($SelfT), ".overflowing_abs(), (10, false));
-assert_eq!((-10", stringify!($SelfT), ").overflowing_abs(), (10, false));
-assert_eq!((", stringify!($SelfT), "::MIN).overflowing_abs(), (", stringify!($SelfT),
-"::MIN, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_abs", since = "1.13.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn overflowing_abs(self) -> (Self, bool) {
- (self.wrapping_abs(), self == Self::MIN)
- }
- }
-
- doc_comment! {
- concat!("Raises self to the power of `exp`, using exponentiation by squaring.
-
-Returns a tuple of the exponentiation along with a bool indicating
-whether an overflow happened.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false));
-assert_eq!(3i8.overflowing_pow(5), (-13, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
- if exp == 0 {
- return (1,false);
- }
- let mut base = self;
- let mut acc: Self = 1;
- let mut overflown = false;
- // Scratch space for storing results of overflowing_mul.
- let mut r;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- r = acc.overflowing_mul(base);
- acc = r.0;
- overflown |= r.1;
- }
- exp /= 2;
- r = base.overflowing_mul(base);
- base = r.0;
- overflown |= r.1;
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- r = acc.overflowing_mul(base);
- r.1 |= overflown;
- r
- }
- }
-
- doc_comment! {
- concat!("Raises self to the power of `exp`, using exponentiation by squaring.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let x: ", stringify!($SelfT), " = 2; // or any other integer type
-
-assert_eq!(x.pow(5), 32);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn pow(self, mut exp: u32) -> Self {
- if exp == 0 {
- return 1;
- }
- let mut base = self;
- let mut acc = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = acc * base;
- }
- exp /= 2;
- base = base * base;
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- acc * base
- }
- }
-
- doc_comment! {
- concat!("Calculates the quotient of Euclidean division of `self` by `rhs`.
-
-This computes the integer `n` such that `self = n * rhs + self.rem_euclid(rhs)`,
-with `0 <= self.rem_euclid(rhs) < rhs`.
-
-In other words, the result is `self / rhs` rounded to the integer `n`
-such that `self >= n * rhs`.
-If `self > 0`, this is equal to round towards zero (the default in Rust);
-if `self < 0`, this is equal to round towards +/- infinity.
-
-# Panics
-
-This function will panic if `rhs` is 0 or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-let a: ", stringify!($SelfT), " = 7; // or any other integer type
-let b = 4;
-
-assert_eq!(a.div_euclid(b), 1); // 7 >= 4 * 1
-assert_eq!(a.div_euclid(-b), -1); // 7 >= -4 * -1
-assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2
-assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn div_euclid(self, rhs: Self) -> Self {
- let q = self / rhs;
- if self % rhs < 0 {
- return if rhs > 0 { q - 1 } else { q + 1 }
- }
- q
- }
- }
-
-
- doc_comment! {
- concat!("Calculates the least nonnegative remainder of `self (mod rhs)`.
-
-This is done as if by the Euclidean division algorithm -- given
-`r = self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
-`0 <= r < abs(rhs)`.
-
-# Panics
-
-This function will panic if `rhs` is 0 or the division results in overflow.
-
-# Examples
-
-Basic usage:
-
-```
-let a: ", stringify!($SelfT), " = 7; // or any other integer type
-let b = 4;
-
-assert_eq!(a.rem_euclid(b), 3);
-assert_eq!((-a).rem_euclid(b), 1);
-assert_eq!(a.rem_euclid(-b), 3);
-assert_eq!((-a).rem_euclid(-b), 1);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn rem_euclid(self, rhs: Self) -> Self {
- let r = self % rhs;
- if r < 0 {
- if rhs < 0 {
- r - rhs
- } else {
- r + rhs
- }
- } else {
- r
- }
- }
- }
-
- doc_comment! {
- concat!("Computes the absolute value of `self`.
-
-# Overflow behavior
-
-The absolute value of `", stringify!($SelfT), "::MIN` cannot be represented as an
-`", stringify!($SelfT), "`, and attempting to calculate it will cause an overflow. This means that
-code in debug mode will trigger a panic on this case and optimized code will return `",
-stringify!($SelfT), "::MIN` without a panic.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(10", stringify!($SelfT), ".abs(), 10);
-assert_eq!((-10", stringify!($SelfT), ").abs(), 10);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[allow(unused_attributes)]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn abs(self) -> Self {
- // Note that the #[inline] above means that the overflow
- // semantics of the subtraction depend on the crate we're being
- // inlined into.
- if self.is_negative() {
- -self
- } else {
- self
- }
- }
- }
-
- doc_comment! {
- concat!("Returns a number representing sign of `self`.
-
- - `0` if the number is zero
- - `1` if the number is positive
- - `-1` if the number is negative
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(10", stringify!($SelfT), ".signum(), 1);
-assert_eq!(0", stringify!($SelfT), ".signum(), 0);
-assert_eq!((-10", stringify!($SelfT), ").signum(), -1);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_sign", since = "1.47.0")]
- #[inline]
- pub const fn signum(self) -> Self {
- match self {
- n if n > 0 => 1,
- 0 => 0,
- _ => -1,
- }
- }
- }
-
- doc_comment! {
- concat!("Returns `true` if `self` is positive and `false` if the number is zero or
-negative.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert!(10", stringify!($SelfT), ".is_positive());
-assert!(!(-10", stringify!($SelfT), ").is_positive());",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn is_positive(self) -> bool { self > 0 }
- }
-
- doc_comment! {
- concat!("Returns `true` if `self` is negative and `false` if the number is zero or
-positive.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert!((-10", stringify!($SelfT), ").is_negative());
-assert!(!10", stringify!($SelfT), ".is_negative());",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
- #[inline]
- pub const fn is_negative(self) -> bool { self < 0 }
- }
-
- doc_comment! {
- concat!("Return the memory representation of this integer as a byte array in
-big-endian (network) byte order.
-",
-$to_xe_bytes_doc,
-"
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
-assert_eq!(bytes, ", $be_bytes, ");
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
- self.to_be().to_ne_bytes()
- }
- }
-
-doc_comment! {
- concat!("Return the memory representation of this integer as a byte array in
-little-endian byte order.
-",
-$to_xe_bytes_doc,
-"
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
-assert_eq!(bytes, ", $le_bytes, ");
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
- self.to_le().to_ne_bytes()
- }
- }
-
- doc_comment! {
- concat!("
-Return the memory representation of this integer as a byte array in
-native byte order.
-
-As the target platform's native endianness is used, portable code
-should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
-instead.
-",
-$to_xe_bytes_doc,
-"
-[`to_be_bytes`]: #method.to_be_bytes
-[`to_le_bytes`]: #method.to_le_bytes
-
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
-assert_eq!(
- bytes,
- if cfg!(target_endian = \"big\") {
- ", $be_bytes, "
- } else {
- ", $le_bytes, "
- }
-);
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- // SAFETY: const sound because integers are plain old datatypes so we can always
- // transmute them to arrays of bytes
- #[allow_internal_unstable(const_fn_transmute)]
- #[inline]
- pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
- // SAFETY: integers are plain old datatypes so we can always transmute them to
- // arrays of bytes
- unsafe { mem::transmute(self) }
- }
- }
-
-doc_comment! {
- concat!("Create an integer value from its representation as a byte array in
-big endian.
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- Self::from_be(Self::from_ne_bytes(bytes))
- }
- }
-
-doc_comment! {
- concat!("
-Create an integer value from its representation as a byte array in
-little endian.
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- Self::from_le(Self::from_ne_bytes(bytes))
- }
- }
-
- doc_comment! {
- concat!("Create an integer value from its memory representation as a byte
-array in native endianness.
-
-As the target platform's native endianness is used, portable code
-likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
-appropriate instead.
-
-[`from_be_bytes`]: #method.from_be_bytes
-[`from_le_bytes`]: #method.from_le_bytes
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
- ", $be_bytes, "
-} else {
- ", $le_bytes, "
-});
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- // SAFETY: const sound because integers are plain old datatypes so we can always
- // transmute to them
- #[allow_internal_unstable(const_fn_transmute)]
- #[inline]
- pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- // SAFETY: integers are plain old datatypes so we can always transmute to them
- unsafe { mem::transmute(bytes) }
- }
- }
-
- doc_comment! {
- concat!("**This method is soft-deprecated.**
-
-Although using it won’t cause compilation warning,
-new code should use [`", stringify!($SelfT), "::MIN", "`](#associatedconstant.MIN) instead.
-
-Returns the smallest value that can be represented by this integer type."),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline(always)]
- #[rustc_promotable]
- #[rustc_const_stable(feature = "const_min_value", since = "1.32.0")]
- pub const fn min_value() -> Self {
- Self::MIN
- }
- }
-
- doc_comment! {
- concat!("**This method is soft-deprecated.**
-
-Although using it won’t cause compilation warning,
-new code should use [`", stringify!($SelfT), "::MAX", "`](#associatedconstant.MAX) instead.
-
-Returns the largest value that can be represented by this integer type."),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline(always)]
- #[rustc_promotable]
- #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
- pub const fn max_value() -> Self {
- Self::MAX
- }
- }
- }
-}
-
#[lang = "i8"]
impl i8 {
int_impl! { i8, i8, u8, 8, -128, 127, "", "", 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
@@ -2567,1948 +154,6 @@
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
}
-macro_rules! uint_impl {
- ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr,
- $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
- $reversed:expr, $le_bytes:expr, $be_bytes:expr,
- $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
- doc_comment! {
- concat!("The smallest value that can be represented by this integer type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, 0);", $EndFeature, "
-```"),
- #[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MIN: Self = 0;
- }
-
- doc_comment! {
- concat!("The largest value that can be represented by this integer type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");",
-$EndFeature, "
-```"),
- #[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MAX: Self = !0;
- }
-
- doc_comment! {
- concat!("Converts a string slice in a given base to an integer.
-
-The string is expected to be an optional `+` sign
-followed by digits.
-Leading and trailing whitespace represent an error.
-Digits are a subset of these characters, depending on `radix`:
-
-* `0-9`
-* `a-z`
-* `A-Z`
-
-# Panics
-
-This function panics if `radix` is not in the range from 2 to 36.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
- from_str_radix(src, radix)
- }
- }
-
- doc_comment! {
- concat!("Returns the number of ones in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0b01001100", stringify!($SelfT), ";
-
-assert_eq!(n.count_ones(), 3);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn count_ones(self) -> u32 {
- intrinsics::ctpop(self as $ActualT) as u32
- }
- }
-
- doc_comment! {
- concat!("Returns the number of zeros in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn count_zeros(self) -> u32 {
- (!self).count_ones()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of leading zeros in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = ", stringify!($SelfT), "::MAX >> 2;
-
-assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn leading_zeros(self) -> u32 {
- intrinsics::ctlz(self as $ActualT) as u32
- }
- }
-
- doc_comment! {
- concat!("Returns the number of trailing zeros in the binary representation
-of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0b0101000", stringify!($SelfT), ";
-
-assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn trailing_zeros(self) -> u32 {
- intrinsics::cttz(self) as u32
- }
- }
-
- doc_comment! {
- concat!("Returns the number of leading ones in the binary representation of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = !(", stringify!($SelfT), "::MAX >> 2);
-
-assert_eq!(n.leading_ones(), 2);", $EndFeature, "
-```"),
- #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[inline]
- pub const fn leading_ones(self) -> u32 {
- (!self).leading_zeros()
- }
- }
-
- doc_comment! {
- concat!("Returns the number of trailing ones in the binary representation
-of `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0b1010111", stringify!($SelfT), ";
-
-assert_eq!(n.trailing_ones(), 3);", $EndFeature, "
-```"),
- #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
- #[inline]
- pub const fn trailing_ones(self) -> u32 {
- (!self).trailing_zeros()
- }
- }
-
- doc_comment! {
- concat!("Shifts the bits to the left by a specified amount, `n`,
-wrapping the truncated bits to the end of the resulting integer.
-
-Please note this isn't the same operation as the `<<` shifting operator!
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $rot_op, stringify!($SelfT), ";
-let m = ", $rot_result, ";
-
-assert_eq!(n.rotate_left(", $rot, "), m);
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn rotate_left(self, n: u32) -> Self {
- intrinsics::rotate_left(self, n as $SelfT)
- }
- }
-
- doc_comment! {
- concat!("Shifts the bits to the right by a specified amount, `n`,
-wrapping the truncated bits to the beginning of the resulting
-integer.
-
-Please note this isn't the same operation as the `>>` shifting operator!
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $rot_result, stringify!($SelfT), ";
-let m = ", $rot_op, ";
-
-assert_eq!(n.rotate_right(", $rot, "), m);
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn rotate_right(self, n: u32) -> Self {
- intrinsics::rotate_right(self, n as $SelfT)
- }
- }
-
- doc_comment! {
- concat!("
-Reverses the byte order of the integer.
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $swap_op, stringify!($SelfT), ";
-let m = n.swap_bytes();
-
-assert_eq!(m, ", $swapped, ");
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn swap_bytes(self) -> Self {
- intrinsics::bswap(self as $ActualT) as Self
- }
- }
-
- doc_comment! {
- concat!("Reverses the bit pattern of the integer.
-
-# Examples
-
-Basic usage:
-
-```
-let n = ", $swap_op, stringify!($SelfT), ";
-let m = n.reverse_bits();
-
-assert_eq!(m, ", $reversed, ");
-```"),
- #[stable(feature = "reverse_bits", since = "1.37.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- #[must_use]
- pub const fn reverse_bits(self) -> Self {
- intrinsics::bitreverse(self as $ActualT) as Self
- }
- }
-
- doc_comment! {
- concat!("Converts an integer from big endian to the target's endianness.
-
-On big endian this is a no-op. On little endian the bytes are
-swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"big\") {
- assert_eq!(", stringify!($SelfT), "::from_be(n), n)
-} else {
- assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
-}", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn from_be(x: Self) -> Self {
- #[cfg(target_endian = "big")]
- {
- x
- }
- #[cfg(not(target_endian = "big"))]
- {
- x.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts an integer from little endian to the target's endianness.
-
-On little endian this is a no-op. On big endian the bytes are
-swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"little\") {
- assert_eq!(", stringify!($SelfT), "::from_le(n), n)
-} else {
- assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
-}", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn from_le(x: Self) -> Self {
- #[cfg(target_endian = "little")]
- {
- x
- }
- #[cfg(not(target_endian = "little"))]
- {
- x.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts `self` to big endian from the target's endianness.
-
-On big endian this is a no-op. On little endian the bytes are
-swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"big\") {
- assert_eq!(n.to_be(), n)
-} else {
- assert_eq!(n.to_be(), n.swap_bytes())
-}", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn to_be(self) -> Self { // or not to be?
- #[cfg(target_endian = "big")]
- {
- self
- }
- #[cfg(not(target_endian = "big"))]
- {
- self.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Converts `self` to little endian from the target's endianness.
-
-On little endian this is a no-op. On big endian the bytes are
-swapped.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "let n = 0x1A", stringify!($SelfT), ";
-
-if cfg!(target_endian = \"little\") {
- assert_eq!(n.to_le(), n)
-} else {
- assert_eq!(n.to_le(), n.swap_bytes())
-}", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
- #[inline]
- pub const fn to_le(self) -> Self {
- #[cfg(target_endian = "little")]
- {
- self
- }
- #[cfg(not(target_endian = "little"))]
- {
- self.swap_bytes()
- }
- }
- }
-
- doc_comment! {
- concat!("Checked integer addition. Computes `self + rhs`, returning `None`
-if overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(1), ",
-"Some(", stringify!($SelfT), "::MAX - 1));
-assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_add(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_add(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT),
-"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_add`.
- unsafe { intrinsics::unchecked_add(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer subtraction. Computes `self - rhs`, returning
-`None` if overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0));
-assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_sub(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT),
-"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_sub`.
- unsafe { intrinsics::unchecked_sub(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer multiplication. Computes `self * rhs`, returning
-`None` if overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5));
-assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
- let (a, b) = self.overflowing_mul(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
-cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT),
-"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."),
- #[unstable(
- feature = "unchecked_math",
- reason = "niche optimization path",
- issue = "none",
- )]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
- // SAFETY: the caller must uphold the safety contract for
- // `unchecked_mul`.
- unsafe { intrinsics::unchecked_mul(self, rhs) }
- }
- }
-
- doc_comment! {
- concat!("Checked integer division. Computes `self / rhs`, returning `None`
-if `rhs == 0`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));
-assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_div(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0) {
- None
- } else {
- // SAFETY: div by zero has been checked above and unsigned types have no other
- // failure modes for division
- Some(unsafe { intrinsics::unchecked_div(self, rhs) })
- }
- }
- }
-
- doc_comment! {
- concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None`
-if `rhs == 0`.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));
-assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0) {
- None
- } else {
- Some(self.div_euclid(rhs))
- }
- }
- }
-
-
- doc_comment! {
- concat!("Checked integer remainder. Computes `self % rhs`, returning `None`
-if `rhs == 0`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
-assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0) {
- None
- } else {
- // SAFETY: div by zero has been checked above and unsigned types have no other
- // failure modes for division
- Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
- }
- }
- }
-
- doc_comment! {
- concat!("Checked Euclidean modulo. Computes `self.rem_euclid(rhs)`, returning `None`
-if `rhs == 0`.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
-assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
- if unlikely!(rhs == 0) {
- None
- } else {
- Some(self.rem_euclid(rhs))
- }
- }
- }
-
- doc_comment! {
- concat!("Checked negation. Computes `-self`, returning `None` unless `self ==
-0`.
-
-Note that negating any positive integer will overflow.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0));
-assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn checked_neg(self) -> Option<Self> {
- let (a, b) = self.overflowing_neg();
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked shift left. Computes `self << rhs`, returning `None`
-if `rhs` is larger than or equal to the number of bits in `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
-assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shl(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked shift right. Computes `self >> rhs`, returning `None`
-if `rhs` is larger than or equal to the number of bits in `self`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
-assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
- let (a, b) = self.overflowing_shr(rhs);
- if unlikely!(b) {None} else {Some(a)}
- }
- }
-
- doc_comment! {
- concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
-overflow occurred.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));
-assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
- if exp == 0 {
- return Some(1);
- }
- let mut base = self;
- let mut acc: Self = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = try_opt!(acc.checked_mul(base));
- }
- exp /= 2;
- base = try_opt!(base.checked_mul(base));
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
-
- Some(try_opt!(acc.checked_mul(base)))
- }
- }
-
- doc_comment! {
- concat!("Saturating integer addition. Computes `self + rhs`, saturating at
-the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);",
-$EndFeature, "
-```"),
-
- #[stable(feature = "rust1", since = "1.0.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn saturating_add(self, rhs: Self) -> Self {
- intrinsics::saturating_add(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Saturating integer subtraction. Computes `self - rhs`, saturating
-at the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
-assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[inline]
- pub const fn saturating_sub(self, rhs: Self) -> Self {
- intrinsics::saturating_sub(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Saturating integer multiplication. Computes `self * rhs`,
-saturating at the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20);
-assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT),
-"::MAX);", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_mul(self, rhs: Self) -> Self {
- match self.checked_mul(rhs) {
- Some(x) => x,
- None => Self::MAX,
- }
- }
- }
-
- doc_comment! {
- concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
-saturating at the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "
-assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);
-assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);",
-$EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn saturating_pow(self, exp: u32) -> Self {
- match self.checked_pow(exp) {
- Some(x) => x,
- None => Self::MAX,
- }
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) addition. Computes `self + rhs`,
-wrapping around at the boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255);
-assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::MAX), 199);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_add(self, rhs: Self) -> Self {
- intrinsics::wrapping_add(self, rhs)
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) subtraction. Computes `self - rhs`,
-wrapping around at the boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0);
-assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::MAX), 101);",
-$EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_sub(self, rhs: Self) -> Self {
- intrinsics::wrapping_sub(self, rhs)
- }
- }
-
- /// Wrapping (modular) multiplication. Computes `self *
- /// rhs`, wrapping around at the boundary of the type.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// Please note that this example is shared between integer types.
- /// Which explains why `u8` is used here.
- ///
- /// ```
- /// assert_eq!(10u8.wrapping_mul(12), 120);
- /// assert_eq!(25u8.wrapping_mul(12), 44);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_mul(self, rhs: Self) -> Self {
- intrinsics::wrapping_mul(self, rhs)
- }
-
- doc_comment! {
- concat!("Wrapping (modular) division. Computes `self / rhs`.
-Wrapped division on unsigned types is just normal division.
-There's no way wrapping could ever happen.
-This function exists, so that all operations
-are accounted for in the wrapping operations.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_div(self, rhs: Self) -> Self {
- self / rhs
- }
- }
-
- doc_comment! {
- concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`.
-Wrapped division on unsigned types is just normal division.
-There's no way wrapping could ever happen.
-This function exists, so that all operations
-are accounted for in the wrapping operations.
-Since, for the positive integers, all common
-definitions of division are equal, this
-is exactly equal to `self.wrapping_div(rhs)`.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
- self / rhs
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) remainder. Computes `self % rhs`.
-Wrapped remainder calculation on unsigned types is
-just the regular remainder calculation.
-There's no way wrapping could ever happen.
-This function exists, so that all operations
-are accounted for in the wrapping operations.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_rem(self, rhs: Self) -> Self {
- self % rhs
- }
- }
-
- doc_comment! {
- concat!("Wrapping Euclidean modulo. Computes `self.rem_euclid(rhs)`.
-Wrapped modulo calculation on unsigned types is
-just the regular remainder calculation.
-There's no way wrapping could ever happen.
-This function exists, so that all operations
-are accounted for in the wrapping operations.
-Since, for the positive integers, all common
-definitions of division are equal, this
-is exactly equal to `self.wrapping_rem(rhs)`.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
- self % rhs
- }
- }
-
- /// Wrapping (modular) negation. Computes `-self`,
- /// wrapping around at the boundary of the type.
- ///
- /// Since unsigned types do not have negative equivalents
- /// all applications of this function will wrap (except for `-0`).
- /// For values smaller than the corresponding signed type's maximum
- /// the result is the same as casting the corresponding signed value.
- /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
- /// `MAX` is the corresponding signed type's maximum.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// Please note that this example is shared between integer types.
- /// Which explains why `i8` is used here.
- ///
- /// ```
- /// assert_eq!(100i8.wrapping_neg(), -100);
- /// assert_eq!((-128i8).wrapping_neg(), -128);
- /// ```
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[inline]
- pub const fn wrapping_neg(self) -> Self {
- self.overflowing_neg().0
- }
-
- doc_comment! {
- concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`,
-where `mask` removes any high-order bits of `rhs` that
-would cause the shift to exceed the bitwidth of the type.
-
-Note that this is *not* the same as a rotate-left; the
-RHS of a wrapping shift-left is restricted to the range
-of the type, rather than the bits shifted out of the LHS
-being returned to the other end. The primitive integer
-types all implement a [`rotate_left`](#method.rotate_left) function,
-which may be what you want instead.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);
-assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_shl(self, rhs: u32) -> Self {
- // SAFETY: the masking by the bitsize of the type ensures that we do not shift
- // out of bounds
- unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
- }
- }
- }
-
- doc_comment! {
- concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
-where `mask` removes any high-order bits of `rhs` that
-would cause the shift to exceed the bitwidth of the type.
-
-Note that this is *not* the same as a rotate-right; the
-RHS of a wrapping shift-right is restricted to the range
-of the type, rather than the bits shifted out of the LHS
-being returned to the other end. The primitive integer
-types all implement a [`rotate_right`](#method.rotate_right) function,
-which may be what you want instead.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);
-assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
-```"),
- #[stable(feature = "num_wrapping", since = "1.2.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_shr(self, rhs: u32) -> Self {
- // SAFETY: the masking by the bitsize of the type ensures that we do not shift
- // out of bounds
- unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
- }
- }
- }
-
- doc_comment! {
- concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
-wrapping around at the boundary of the type.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);
-assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn wrapping_pow(self, mut exp: u32) -> Self {
- if exp == 0 {
- return 1;
- }
- let mut base = self;
- let mut acc: Self = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = acc.wrapping_mul(base);
- }
- exp /= 2;
- base = base.wrapping_mul(base);
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- acc.wrapping_mul(base)
- }
- }
-
- doc_comment! {
- concat!("Calculates `self` + `rhs`
-
-Returns a tuple of the addition along with a boolean indicating
-whether an arithmetic overflow would occur. If an overflow would
-have occurred then the wrapped value is returned.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
-assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
- }
-
- doc_comment! {
- concat!("Calculates `self` - `rhs`
-
-Returns a tuple of the subtraction along with a boolean indicating
-whether an arithmetic overflow would occur. If an overflow would
-have occurred then the wrapped value is returned.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "
-assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
-assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));",
-$EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
- }
-
- /// Calculates the multiplication of `self` and `rhs`.
- ///
- /// Returns a tuple of the multiplication along with a boolean
- /// indicating whether an arithmetic overflow would occur. If an
- /// overflow would have occurred then the wrapped value is returned.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// Please note that this example is shared between integer types.
- /// Which explains why `u32` is used here.
- ///
- /// ```
- /// assert_eq!(5u32.overflowing_mul(2), (10, false));
- /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
- /// ```
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
- let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
- (a as Self, b)
- }
-
- doc_comment! {
- concat!("Calculates the divisor when `self` is divided by `rhs`.
-
-Returns a tuple of the divisor along with a boolean indicating
-whether an arithmetic overflow would occur. Note that for unsigned
-integers overflow never occurs, so the second value is always
-`false`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));", $EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
- (self / rhs, false)
- }
- }
-
- doc_comment! {
- concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
-
-Returns a tuple of the divisor along with a boolean indicating
-whether an arithmetic overflow would occur. Note that for unsigned
-integers overflow never occurs, so the second value is always
-`false`.
-Since, for the positive integers, all common
-definitions of division are equal, this
-is exactly equal to `self.overflowing_div(rhs)`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage
-
-```
-assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
-```"),
- #[inline]
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
- (self / rhs, false)
- }
- }
-
- doc_comment! {
- concat!("Calculates the remainder when `self` is divided by `rhs`.
-
-Returns a tuple of the remainder after dividing along with a boolean
-indicating whether an arithmetic overflow would occur. Note that for
-unsigned integers overflow never occurs, so the second value is
-always `false`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));", $EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
- (self % rhs, false)
- }
- }
-
- doc_comment! {
- concat!("Calculates the remainder `self.rem_euclid(rhs)` as if by Euclidean division.
-
-Returns a tuple of the modulo after dividing along with a boolean
-indicating whether an arithmetic overflow would occur. Note that for
-unsigned integers overflow never occurs, so the second value is
-always `false`.
-Since, for the positive integers, all common
-definitions of division are equal, this operation
-is exactly equal to `self.overflowing_rem(rhs)`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage
-
-```
-assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
-```"),
- #[inline]
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
- (self % rhs, false)
- }
- }
-
- doc_comment! {
- concat!("Negates self in an overflowing fashion.
-
-Returns `!self + 1` using wrapping operations to return the value
-that represents the negation of this unsigned value. Note that for
-positive unsigned values overflow always occurs, but negating 0 does
-not overflow.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));
-assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT),
-", true));", $EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- pub const fn overflowing_neg(self) -> (Self, bool) {
- ((!self).wrapping_add(1), self != 0)
- }
- }
-
- doc_comment! {
- concat!("Shifts self left by `rhs` bits.
-
-Returns a tuple of the shifted version of self along with a boolean
-indicating whether the shift value was larger than or equal to the
-number of bits. If the shift value is too large, then value is
-masked (N-1) where N is the number of bits, and this value is then
-used to perform the shift.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));
-assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
- }
- }
-
- doc_comment! {
- concat!("Shifts self right by `rhs` bits.
-
-Returns a tuple of the shifted version of self along with a boolean
-indicating whether the shift value was larger than or equal to the
-number of bits. If the shift value is too large, then value is
-masked (N-1) where N is the number of bits, and this value is then
-used to perform the shift.
-
-# Examples
-
-Basic usage
-
-```
-", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
-assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
-```"),
- #[stable(feature = "wrapping", since = "1.7.0")]
- #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
- }
- }
-
- doc_comment! {
- concat!("Raises self to the power of `exp`, using exponentiation by squaring.
-
-Returns a tuple of the exponentiation along with a bool indicating
-whether an overflow happened.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));
-assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
-```"),
- #[stable(feature = "no_panic_pow", since = "1.34.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
- if exp == 0{
- return (1,false);
- }
- let mut base = self;
- let mut acc: Self = 1;
- let mut overflown = false;
- // Scratch space for storing results of overflowing_mul.
- let mut r;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- r = acc.overflowing_mul(base);
- acc = r.0;
- overflown |= r.1;
- }
- exp /= 2;
- r = base.overflowing_mul(base);
- base = r.0;
- overflown |= r.1;
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- r = acc.overflowing_mul(base);
- r.1 |= overflown;
-
- r
- }
- }
-
- doc_comment! {
- concat!("Raises self to the power of `exp`, using exponentiation by squaring.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn pow(self, mut exp: u32) -> Self {
- if exp == 0 {
- return 1;
- }
- let mut base = self;
- let mut acc = 1;
-
- while exp > 1 {
- if (exp & 1) == 1 {
- acc = acc * base;
- }
- exp /= 2;
- base = base * base;
- }
-
- // since exp!=0, finally the exp must be 1.
- // Deal with the final bit of the exponent separately, since
- // squaring the base afterwards is not necessary and may cause a
- // needless overflow.
- acc * base
- }
- }
-
- doc_comment! {
- concat!("Performs Euclidean division.
-
-Since, for the positive integers, all common
-definitions of division are equal, this
-is exactly equal to `self / rhs`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn div_euclid(self, rhs: Self) -> Self {
- self / rhs
- }
- }
-
-
- doc_comment! {
- concat!("Calculates the least remainder of `self (mod rhs)`.
-
-Since, for the positive integers, all common
-definitions of division are equal, this
-is exactly equal to `self % rhs`.
-
-# Panics
-
-This function will panic if `rhs` is 0.
-
-# Examples
-
-Basic usage:
-
-```
-assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type
-```"),
- #[stable(feature = "euclidean_division", since = "1.38.0")]
- #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
- #[must_use = "this returns the result of the operation, \
- without modifying the original"]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn rem_euclid(self, rhs: Self) -> Self {
- self % rhs
- }
- }
-
- doc_comment! {
- concat!("Returns `true` if and only if `self == 2^k` for some `k`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert!(16", stringify!($SelfT), ".is_power_of_two());
-assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")]
- #[inline]
- pub const fn is_power_of_two(self) -> bool {
- self.count_ones() == 1
- }
- }
-
- // Returns one less than next power of two.
- // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8)
- //
- // 8u8.one_less_than_next_power_of_two() == 7
- // 6u8.one_less_than_next_power_of_two() == 7
- //
- // This method cannot overflow, as in the `next_power_of_two`
- // overflow cases it instead ends up returning the maximum value
- // of the type, and can return 0 for 0.
- #[inline]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- const fn one_less_than_next_power_of_two(self) -> Self {
- if self <= 1 { return 0; }
-
- let p = self - 1;
- // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
- // That means the shift is always in-bounds, and some processors
- // (such as intel pre-haswell) have more efficient ctlz
- // intrinsics when the argument is non-zero.
- let z = unsafe { intrinsics::ctlz_nonzero(p) };
- <$SelfT>::MAX >> z
- }
-
- doc_comment! {
- concat!("Returns the smallest power of two greater than or equal to `self`.
-
-When return value overflows (i.e., `self > (1 << (N-1))` for type
-`uN`), it panics in debug mode and return value is wrapped to 0 in
-release mode (the only situation in which method can return 0).
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);
-assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
-```"),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- #[inline]
- #[rustc_inherit_overflow_checks]
- pub const fn next_power_of_two(self) -> Self {
- self.one_less_than_next_power_of_two() + 1
- }
- }
-
- doc_comment! {
- concat!("Returns the smallest power of two greater than or equal to `n`. If
-the next power of two is greater than the type's maximum value,
-`None` is returned, otherwise the power of two is wrapped in `Some`.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(2", stringify!($SelfT),
-".checked_next_power_of_two(), Some(2));
-assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4));
-assert_eq!(", stringify!($SelfT), "::MAX.checked_next_power_of_two(), None);",
-$EndFeature, "
-```"),
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- pub const fn checked_next_power_of_two(self) -> Option<Self> {
- self.one_less_than_next_power_of_two().checked_add(1)
- }
- }
-
- doc_comment! {
- concat!("Returns the smallest power of two greater than or equal to `n`. If
-the next power of two is greater than the type's maximum value,
-the return value is wrapped to `0`.
-
-# Examples
-
-Basic usage:
-
-```
-#![feature(wrapping_next_power_of_two)]
-", $Feature, "
-assert_eq!(2", stringify!($SelfT), ".wrapping_next_power_of_two(), 2);
-assert_eq!(3", stringify!($SelfT), ".wrapping_next_power_of_two(), 4);
-assert_eq!(", stringify!($SelfT), "::MAX.wrapping_next_power_of_two(), 0);",
-$EndFeature, "
-```"),
- #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
- reason = "needs decision on wrapping behaviour")]
- #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
- pub const fn wrapping_next_power_of_two(self) -> Self {
- self.one_less_than_next_power_of_two().wrapping_add(1)
- }
- }
-
- doc_comment! {
- concat!("Return the memory representation of this integer as a byte array in
-big-endian (network) byte order.
-",
-$to_xe_bytes_doc,
-"
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
-assert_eq!(bytes, ", $be_bytes, ");
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
- self.to_be().to_ne_bytes()
- }
- }
-
- doc_comment! {
- concat!("Return the memory representation of this integer as a byte array in
-little-endian byte order.
-",
-$to_xe_bytes_doc,
-"
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
-assert_eq!(bytes, ", $le_bytes, ");
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
- self.to_le().to_ne_bytes()
- }
- }
-
- doc_comment! {
- concat!("
-Return the memory representation of this integer as a byte array in
-native byte order.
-
-As the target platform's native endianness is used, portable code
-should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
-instead.
-",
-$to_xe_bytes_doc,
-"
-[`to_be_bytes`]: #method.to_be_bytes
-[`to_le_bytes`]: #method.to_le_bytes
-
-# Examples
-
-```
-let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
-assert_eq!(
- bytes,
- if cfg!(target_endian = \"big\") {
- ", $be_bytes, "
- } else {
- ", $le_bytes, "
- }
-);
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- // SAFETY: const sound because integers are plain old datatypes so we can always
- // transmute them to arrays of bytes
- #[allow_internal_unstable(const_fn_transmute)]
- #[inline]
- pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
- // SAFETY: integers are plain old datatypes so we can always transmute them to
- // arrays of bytes
- unsafe { mem::transmute(self) }
- }
- }
-
- doc_comment! {
- concat!("Create a native endian integer value from its representation
-as a byte array in big endian.
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- Self::from_be(Self::from_ne_bytes(bytes))
- }
- }
-
- doc_comment! {
- concat!("
-Create a native endian integer value from its representation
-as a byte array in little endian.
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- #[inline]
- pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- Self::from_le(Self::from_ne_bytes(bytes))
- }
- }
-
- doc_comment! {
- concat!("Create a native endian integer value from its memory representation
-as a byte array in native endianness.
-
-As the target platform's native endianness is used, portable code
-likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
-appropriate instead.
-
-[`from_be_bytes`]: #method.from_be_bytes
-[`from_le_bytes`]: #method.from_le_bytes
-",
-$from_xe_bytes_doc,
-"
-# Examples
-
-```
-let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
- ", $be_bytes, "
-} else {
- ", $le_bytes, "
-});
-assert_eq!(value, ", $swap_op, ");
-```
-
-When starting from a slice rather than an array, fallible conversion APIs can be used:
-
-```
-use std::convert::TryInto;
-
-fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
- let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
- *input = rest;
- ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
-}
-```"),
- #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
- #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
- // SAFETY: const sound because integers are plain old datatypes so we can always
- // transmute to them
- #[allow_internal_unstable(const_fn_transmute)]
- #[inline]
- pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- // SAFETY: integers are plain old datatypes so we can always transmute to them
- unsafe { mem::transmute(bytes) }
- }
- }
-
- doc_comment! {
- concat!("**This method is soft-deprecated.**
-
-Although using it won’t cause compilation warning,
-new code should use [`", stringify!($SelfT), "::MIN", "`](#associatedconstant.MIN) instead.
-
-Returns the smallest value that can be represented by this integer type."),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_promotable]
- #[inline(always)]
- #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
- pub const fn min_value() -> Self { Self::MIN }
- }
-
- doc_comment! {
- concat!("**This method is soft-deprecated.**
-
-Although using it won’t cause compilation warning,
-new code should use [`", stringify!($SelfT), "::MAX", "`](#associatedconstant.MAX) instead.
-
-Returns the largest value that can be represented by this integer type."),
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_promotable]
- #[inline(always)]
- #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
- pub const fn max_value() -> Self { Self::MAX }
- }
- }
-}
-
#[lang = "u8"]
impl u8 {
uint_impl! { u8, u8, 8, 255, "", "", 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
@@ -5115,6 +760,16 @@
Normal,
}
+#[doc(hidden)]
+trait FromStrRadixHelper: PartialOrd + Copy {
+ fn min_value() -> Self;
+ fn max_value() -> Self;
+ fn from_u32(u: u32) -> Self;
+ fn checked_mul(&self, other: u32) -> Option<Self>;
+ fn checked_sub(&self, other: u32) -> Option<Self>;
+ fn checked_add(&self, other: u32) -> Option<Self>;
+}
+
macro_rules! from_str_radix_int_impl {
($($t:ty)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
@@ -5128,58 +783,6 @@
}
from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
-/// The error type returned when a checked integral type conversion fails.
-#[stable(feature = "try_from", since = "1.34.0")]
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct TryFromIntError(pub(crate) ());
-
-impl TryFromIntError {
- #[unstable(
- feature = "int_error_internals",
- reason = "available through Error trait and this method should \
- not be exposed publicly",
- issue = "none"
- )]
- #[doc(hidden)]
- pub fn __description(&self) -> &str {
- "out of range integral type conversion attempted"
- }
-}
-
-#[stable(feature = "try_from", since = "1.34.0")]
-impl fmt::Display for TryFromIntError {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.__description().fmt(fmt)
- }
-}
-
-#[stable(feature = "try_from", since = "1.34.0")]
-impl From<Infallible> for TryFromIntError {
- fn from(x: Infallible) -> TryFromIntError {
- match x {}
- }
-}
-
-#[unstable(feature = "never_type", issue = "35121")]
-impl From<!> for TryFromIntError {
- fn from(never: !) -> TryFromIntError {
- // Match rather than coerce to make sure that code like
- // `From<Infallible> for TryFromIntError` above will keep working
- // when `Infallible` becomes an alias to `!`.
- match never {}
- }
-}
-
-#[doc(hidden)]
-trait FromStrRadixHelper: PartialOrd + Copy {
- fn min_value() -> Self;
- fn max_value() -> Self;
- fn from_u32(u: u32) -> Self;
- fn checked_mul(&self, other: u32) -> Option<Self>;
- fn checked_sub(&self, other: u32) -> Option<Self>;
- fn checked_add(&self, other: u32) -> Option<Self>;
-}
-
macro_rules! doit {
($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
#[inline]
@@ -5272,91 +875,3 @@
}
Ok(result)
}
-
-/// An error which can be returned when parsing an integer.
-///
-/// This error is used as the error type for the `from_str_radix()` functions
-/// on the primitive integer types, such as [`i8::from_str_radix`].
-///
-/// # Potential causes
-///
-/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
-/// in the string e.g., when it is obtained from the standard input.
-/// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
-///
-/// [`str.trim()`]: ../../std/primitive.str.html#method.trim
-/// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ParseIntError {
- kind: IntErrorKind,
-}
-
-/// Enum to store the various types of errors that can cause parsing an integer to fail.
-#[unstable(
- feature = "int_error_matching",
- reason = "it can be useful to match errors when making error messages \
- for integer parsing",
- issue = "22639"
-)]
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[non_exhaustive]
-pub enum IntErrorKind {
- /// Value being parsed is empty.
- ///
- /// Among other causes, this variant will be constructed when parsing an empty string.
- Empty,
- /// Contains an invalid digit.
- ///
- /// Among other causes, this variant will be constructed when parsing a string that
- /// contains a letter.
- InvalidDigit,
- /// Integer is too large to store in target integer type.
- Overflow,
- /// Integer is too small to store in target integer type.
- Underflow,
- /// Value was Zero
- ///
- /// This variant will be emitted when the parsing string has a value of zero, which
- /// would be illegal for non-zero types.
- Zero,
-}
-
-impl ParseIntError {
- /// Outputs the detailed cause of parsing an integer failing.
- #[unstable(
- feature = "int_error_matching",
- reason = "it can be useful to match errors when making error messages \
- for integer parsing",
- issue = "22639"
- )]
- pub fn kind(&self) -> &IntErrorKind {
- &self.kind
- }
- #[unstable(
- feature = "int_error_internals",
- reason = "available through Error trait and this method should \
- not be exposed publicly",
- issue = "none"
- )]
- #[doc(hidden)]
- pub fn __description(&self) -> &str {
- match self.kind {
- IntErrorKind::Empty => "cannot parse integer from empty string",
- IntErrorKind::InvalidDigit => "invalid digit found in string",
- IntErrorKind::Overflow => "number too large to fit in target type",
- IntErrorKind::Underflow => "number too small to fit in target type",
- IntErrorKind::Zero => "number would be zero for non-zero type",
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for ParseIntError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.__description().fmt(f)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::num::dec2flt::ParseFloatError;
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
new file mode 100644
index 0000000..382f799
--- /dev/null
+++ b/library/core/src/num/nonzero.rs
@@ -0,0 +1,190 @@
+//! Definitions of integer that is known not to equal zero.
+
+use crate::fmt;
+use crate::ops::{BitOr, BitOrAssign};
+use crate::str::FromStr;
+
+use super::from_str_radix;
+use super::{IntErrorKind, ParseIntError};
+
+macro_rules! doc_comment {
+ ($x:expr, $($tt:tt)*) => {
+ #[doc = $x]
+ $($tt)*
+ };
+}
+
+macro_rules! impl_nonzero_fmt {
+ ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+ $(
+ #[$stability]
+ impl fmt::$Trait for $Ty {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.get().fmt(f)
+ }
+ }
+ )+
+ }
+}
+
+macro_rules! nonzero_integers {
+ ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
+ $(
+ doc_comment! {
+ concat!("An integer that is known not to equal zero.
+
+This enables some memory layout optimization.
+For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:
+
+```rust
+use std::mem::size_of;
+assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
+">());
+```"),
+ #[$stability]
+ #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+ #[repr(transparent)]
+ #[rustc_layout_scalar_valid_range_start(1)]
+ #[rustc_nonnull_optimization_guaranteed]
+ pub struct $Ty($Int);
+ }
+
+ impl $Ty {
+ /// Creates a non-zero without checking the value.
+ ///
+ /// # Safety
+ ///
+ /// The value must not be zero.
+ #[$stability]
+ #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
+ #[inline]
+ pub const unsafe fn new_unchecked(n: $Int) -> Self {
+ // SAFETY: this is guaranteed to be safe by the caller.
+ unsafe { Self(n) }
+ }
+
+ /// Creates a non-zero if the given value is not zero.
+ #[$stability]
+ #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn new(n: $Int) -> Option<Self> {
+ if n != 0 {
+ // SAFETY: we just checked that there's no `0`
+ Some(unsafe { Self(n) })
+ } else {
+ None
+ }
+ }
+
+ /// Returns the value as a primitive type.
+ #[$stability]
+ #[inline]
+ #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
+ pub const fn get(self) -> $Int {
+ self.0
+ }
+
+ }
+
+ #[stable(feature = "from_nonzero", since = "1.31.0")]
+ impl From<$Ty> for $Int {
+ doc_comment! {
+ concat!(
+"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
+ fn from(nonzero: $Ty) -> Self {
+ nonzero.0
+ }
+ }
+ }
+
+ #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+ impl BitOr for $Ty {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, rhs: Self) -> Self::Output {
+ // SAFETY: since `self` and `rhs` are both nonzero, the
+ // result of the bitwise-or will be nonzero.
+ unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
+ }
+ }
+
+ #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+ impl BitOr<$Int> for $Ty {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, rhs: $Int) -> Self::Output {
+ // SAFETY: since `self` is nonzero, the result of the
+ // bitwise-or will be nonzero regardless of the value of
+ // `rhs`.
+ unsafe { $Ty::new_unchecked(self.get() | rhs) }
+ }
+ }
+
+ #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+ impl BitOr<$Ty> for $Int {
+ type Output = $Ty;
+ #[inline]
+ fn bitor(self, rhs: $Ty) -> Self::Output {
+ // SAFETY: since `rhs` is nonzero, the result of the
+ // bitwise-or will be nonzero regardless of the value of
+ // `self`.
+ unsafe { $Ty::new_unchecked(self | rhs.get()) }
+ }
+ }
+
+ #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+ impl BitOrAssign for $Ty {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: Self) {
+ *self = *self | rhs;
+ }
+ }
+
+ #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+ impl BitOrAssign<$Int> for $Ty {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: $Int) {
+ *self = *self | rhs;
+ }
+ }
+
+ impl_nonzero_fmt! {
+ #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+ }
+ )+
+ }
+}
+
+nonzero_integers! {
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
+}
+
+macro_rules! from_str_radix_nzint_impl {
+ ($($t:ty)*) => {$(
+ #[stable(feature = "nonzero_parse", since = "1.35.0")]
+ impl FromStr for $t {
+ type Err = ParseIntError;
+ fn from_str(src: &str) -> Result<Self, Self::Err> {
+ Self::new(from_str_radix(src, 10)?)
+ .ok_or(ParseIntError {
+ kind: IntErrorKind::Zero
+ })
+ }
+ }
+ )*}
+}
+
+from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
+NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
diff --git a/library/core/src/num/i128.rs b/library/core/src/num/shells/i128.rs
similarity index 100%
rename from library/core/src/num/i128.rs
rename to library/core/src/num/shells/i128.rs
diff --git a/library/core/src/num/i16.rs b/library/core/src/num/shells/i16.rs
similarity index 100%
rename from library/core/src/num/i16.rs
rename to library/core/src/num/shells/i16.rs
diff --git a/library/core/src/num/i32.rs b/library/core/src/num/shells/i32.rs
similarity index 100%
rename from library/core/src/num/i32.rs
rename to library/core/src/num/shells/i32.rs
diff --git a/library/core/src/num/i64.rs b/library/core/src/num/shells/i64.rs
similarity index 100%
rename from library/core/src/num/i64.rs
rename to library/core/src/num/shells/i64.rs
diff --git a/library/core/src/num/i8.rs b/library/core/src/num/shells/i8.rs
similarity index 100%
rename from library/core/src/num/i8.rs
rename to library/core/src/num/shells/i8.rs
diff --git a/library/core/src/num/shells/int_macros.rs b/library/core/src/num/shells/int_macros.rs
new file mode 100644
index 0000000..ffd30b0
--- /dev/null
+++ b/library/core/src/num/shells/int_macros.rs
@@ -0,0 +1,49 @@
+#![doc(hidden)]
+
+macro_rules! doc_comment {
+ ($x:expr, $($tt:tt)*) => {
+ #[doc = $x]
+ $($tt)*
+ };
+}
+
+macro_rules! int_module {
+ ($T:ident) => (int_module!($T, #[stable(feature = "rust1", since = "1.0.0")]););
+ ($T:ident, #[$attr:meta]) => (
+ doc_comment! {
+ concat!("The smallest value that can be represented by this integer type.
+Use [`", stringify!($T), "::MIN", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MIN) instead.
+
+# Examples
+
+```rust
+// deprecated way
+let min = std::", stringify!($T), "::MIN;
+
+// intended way
+let min = ", stringify!($T), "::MIN;
+```
+"),
+ #[$attr]
+ pub const MIN: $T = $T::MIN;
+ }
+
+ doc_comment! {
+ concat!("The largest value that can be represented by this integer type.
+Use [`", stringify!($T), "::MAX", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MAX) instead.
+
+# Examples
+
+```rust
+// deprecated way
+let max = std::", stringify!($T), "::MAX;
+
+// intended way
+let max = ", stringify!($T), "::MAX;
+```
+"),
+ #[$attr]
+ pub const MAX: $T = $T::MAX;
+ }
+ )
+}
diff --git a/library/core/src/num/isize.rs b/library/core/src/num/shells/isize.rs
similarity index 100%
rename from library/core/src/num/isize.rs
rename to library/core/src/num/shells/isize.rs
diff --git a/library/core/src/num/u128.rs b/library/core/src/num/shells/u128.rs
similarity index 100%
rename from library/core/src/num/u128.rs
rename to library/core/src/num/shells/u128.rs
diff --git a/library/core/src/num/u16.rs b/library/core/src/num/shells/u16.rs
similarity index 100%
rename from library/core/src/num/u16.rs
rename to library/core/src/num/shells/u16.rs
diff --git a/library/core/src/num/u32.rs b/library/core/src/num/shells/u32.rs
similarity index 100%
rename from library/core/src/num/u32.rs
rename to library/core/src/num/shells/u32.rs
diff --git a/library/core/src/num/u64.rs b/library/core/src/num/shells/u64.rs
similarity index 100%
rename from library/core/src/num/u64.rs
rename to library/core/src/num/shells/u64.rs
diff --git a/library/core/src/num/u8.rs b/library/core/src/num/shells/u8.rs
similarity index 100%
rename from library/core/src/num/u8.rs
rename to library/core/src/num/shells/u8.rs
diff --git a/library/core/src/num/usize.rs b/library/core/src/num/shells/usize.rs
similarity index 100%
rename from library/core/src/num/usize.rs
rename to library/core/src/num/shells/usize.rs
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
new file mode 100644
index 0000000..234c309
--- /dev/null
+++ b/library/core/src/num/uint_macros.rs
@@ -0,0 +1,1955 @@
+macro_rules! uint_impl {
+ ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr,
+ $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
+ $reversed:expr, $le_bytes:expr, $be_bytes:expr,
+ $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
+ doc_comment! {
+ concat!("The smallest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MIN, 0);", $EndFeature, "
+```"),
+ #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+ pub const MIN: Self = 0;
+ }
+
+ doc_comment! {
+ concat!("The largest value that can be represented by this integer type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");",
+$EndFeature, "
+```"),
+ #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+ pub const MAX: Self = !0;
+ }
+
+ doc_comment! {
+ concat!("The size of this integer type in bits.
+
+# Examples
+
+```
+", $Feature, "#![feature(int_bits_const)]
+assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");",
+$EndFeature, "
+```"),
+ #[unstable(feature = "int_bits_const", issue = "76904")]
+ pub const BITS: u32 = $BITS;
+ }
+
+ doc_comment! {
+ concat!("Converts a string slice in a given base to an integer.
+
+The string is expected to be an optional `+` sign
+followed by digits.
+Leading and trailing whitespace represent an error.
+Digits are a subset of these characters, depending on `radix`:
+
+* `0-9`
+* `a-z`
+* `A-Z`
+
+# Panics
+
+This function panics if `radix` is not in the range from 2 to 36.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
+ from_str_radix(src, radix)
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b01001100", stringify!($SelfT), ";
+
+assert_eq!(n.count_ones(), 3);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn count_ones(self) -> u32 {
+ intrinsics::ctpop(self as $ActualT) as u32
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn count_zeros(self) -> u32 {
+ (!self).count_ones()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of leading zeros in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = ", stringify!($SelfT), "::MAX >> 2;
+
+assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn leading_zeros(self) -> u32 {
+ intrinsics::ctlz(self as $ActualT) as u32
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of trailing zeros in the binary representation
+of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b0101000", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn trailing_zeros(self) -> u32 {
+ intrinsics::cttz(self) as u32
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of leading ones in the binary representation of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = !(", stringify!($SelfT), "::MAX >> 2);
+
+assert_eq!(n.leading_ones(), 2);", $EndFeature, "
+```"),
+ #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[inline]
+ pub const fn leading_ones(self) -> u32 {
+ (!self).leading_zeros()
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the number of trailing ones in the binary representation
+of `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0b1010111", stringify!($SelfT), ";
+
+assert_eq!(n.trailing_ones(), 3);", $EndFeature, "
+```"),
+ #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+ #[inline]
+ pub const fn trailing_ones(self) -> u32 {
+ (!self).trailing_zeros()
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts the bits to the left by a specified amount, `n`,
+wrapping the truncated bits to the end of the resulting integer.
+
+Please note this isn't the same operation as the `<<` shifting operator!
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $rot_op, stringify!($SelfT), ";
+let m = ", $rot_result, ";
+
+assert_eq!(n.rotate_left(", $rot, "), m);
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn rotate_left(self, n: u32) -> Self {
+ intrinsics::rotate_left(self, n as $SelfT)
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts the bits to the right by a specified amount, `n`,
+wrapping the truncated bits to the beginning of the resulting
+integer.
+
+Please note this isn't the same operation as the `>>` shifting operator!
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $rot_result, stringify!($SelfT), ";
+let m = ", $rot_op, ";
+
+assert_eq!(n.rotate_right(", $rot, "), m);
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn rotate_right(self, n: u32) -> Self {
+ intrinsics::rotate_right(self, n as $SelfT)
+ }
+ }
+
+ doc_comment! {
+ concat!("
+Reverses the byte order of the integer.
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $swap_op, stringify!($SelfT), ";
+let m = n.swap_bytes();
+
+assert_eq!(m, ", $swapped, ");
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn swap_bytes(self) -> Self {
+ intrinsics::bswap(self as $ActualT) as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Reverses the bit pattern of the integer.
+
+# Examples
+
+Basic usage:
+
+```
+let n = ", $swap_op, stringify!($SelfT), ";
+let m = n.reverse_bits();
+
+assert_eq!(m, ", $reversed, ");
+```"),
+ #[stable(feature = "reverse_bits", since = "1.37.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ #[must_use]
+ pub const fn reverse_bits(self) -> Self {
+ intrinsics::bitreverse(self as $ActualT) as Self
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from big endian to the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn from_be(x: Self) -> Self {
+ #[cfg(target_endian = "big")]
+ {
+ x
+ }
+ #[cfg(not(target_endian = "big"))]
+ {
+ x.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts an integer from little endian to the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n)
+} else {
+ assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ x.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to big endian from the target's endianness.
+
+On big endian this is a no-op. On little endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"big\") {
+ assert_eq!(n.to_be(), n)
+} else {
+ assert_eq!(n.to_be(), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn to_be(self) -> Self { // or not to be?
+ #[cfg(target_endian = "big")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "big"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Converts `self` to little endian from the target's endianness.
+
+On little endian this is a no-op. On big endian the bytes are
+swapped.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "let n = 0x1A", stringify!($SelfT), ";
+
+if cfg!(target_endian = \"little\") {
+ assert_eq!(n.to_le(), n)
+} else {
+ assert_eq!(n.to_le(), n.swap_bytes())
+}", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+ #[inline]
+ pub const fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer addition. Computes `self + rhs`, returning `None`
+if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(1), ",
+"Some(", stringify!($SelfT), "::MAX - 1));
+assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer addition. Computes `self + rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self + rhs > ", stringify!($SelfT),
+"::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_add(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_add`.
+ unsafe { intrinsics::unchecked_add(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer subtraction. Computes `self - rhs`, returning
+`None` if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0));
+assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_sub(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self - rhs > ", stringify!($SelfT),
+"::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_sub(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_sub`.
+ unsafe { intrinsics::unchecked_sub(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer multiplication. Computes `self * rhs`, returning
+`None` if overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5));
+assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_mul(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
+cannot occur. This results in undefined behavior when `self * rhs > ", stringify!($SelfT),
+"::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`."),
+ #[unstable(
+ feature = "unchecked_math",
+ reason = "niche optimization path",
+ issue = "none",
+ )]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub unsafe fn unchecked_mul(self, rhs: Self) -> Self {
+ // SAFETY: the caller must uphold the safety contract for
+ // `unchecked_mul`.
+ unsafe { intrinsics::unchecked_mul(self, rhs) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked integer division. Computes `self / rhs`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));
+assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_div(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0) {
+ None
+ } else {
+ // SAFETY: div by zero has been checked above and unsigned types have no other
+ // failure modes for division
+ Some(unsafe { intrinsics::unchecked_div(self, rhs) })
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));
+assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0) {
+ None
+ } else {
+ Some(self.div_euclid(rhs))
+ }
+ }
+ }
+
+
+ doc_comment! {
+ concat!("Checked integer remainder. Computes `self % rhs`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_checked_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0) {
+ None
+ } else {
+ // SAFETY: div by zero has been checked above and unsigned types have no other
+ // failure modes for division
+ Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked Euclidean modulo. Computes `self.rem_euclid(rhs)`, returning `None`
+if `rhs == 0`.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
+assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
+ if unlikely!(rhs == 0) {
+ None
+ } else {
+ Some(self.rem_euclid(rhs))
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked negation. Computes `-self`, returning `None` unless `self ==
+0`.
+
+Note that negating any positive integer will overflow.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0));
+assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn checked_neg(self) -> Option<Self> {
+ let (a, b) = self.overflowing_neg();
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked shift left. Computes `self << rhs`, returning `None`
+if `rhs` is larger than or equal to the number of bits in `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shl(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked shift right. Computes `self >> rhs`, returning `None`
+if `rhs` is larger than or equal to the number of bits in `self`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));
+assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
+ let (a, b) = self.overflowing_shr(rhs);
+ if unlikely!(b) {None} else {Some(a)}
+ }
+ }
+
+ doc_comment! {
+ concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));
+assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
+ if exp == 0 {
+ return Some(1);
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = try_opt!(acc.checked_mul(base));
+ }
+ exp /= 2;
+ base = try_opt!(base.checked_mul(base));
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+
+ Some(try_opt!(acc.checked_mul(base)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer addition. Computes `self + rhs`, saturating at
+the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);",
+$EndFeature, "
+```"),
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn saturating_add(self, rhs: Self) -> Self {
+ intrinsics::saturating_add(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer subtraction. Computes `self - rhs`, saturating
+at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
+assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[inline]
+ pub const fn saturating_sub(self, rhs: Self) -> Self {
+ intrinsics::saturating_sub(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer multiplication. Computes `self * rhs`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20);
+assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT),
+"::MAX);", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_mul(self, rhs: Self) -> Self {
+ match self.checked_mul(rhs) {
+ Some(x) => x,
+ None => Self::MAX,
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "
+assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);",
+$EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn saturating_pow(self, exp: u32) -> Self {
+ match self.checked_pow(exp) {
+ Some(x) => x,
+ None => Self::MAX,
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) addition. Computes `self + rhs`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255);
+assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::MAX), 199);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_add(self, rhs: Self) -> Self {
+ intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) subtraction. Computes `self - rhs`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0);
+assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::MAX), 101);",
+$EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_sub(self, rhs: Self) -> Self {
+ intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ /// Wrapping (modular) multiplication. Computes `self *
+ /// rhs`, wrapping around at the boundary of the type.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u8` is used here.
+ ///
+ /// ```
+ /// assert_eq!(10u8.wrapping_mul(12), 120);
+ /// assert_eq!(25u8.wrapping_mul(12), 44);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_mul(self, rhs: Self) -> Self {
+ intrinsics::wrapping_mul(self, rhs)
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) division. Computes `self / rhs`.
+Wrapped division on unsigned types is just normal division.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_div(self, rhs: Self) -> Self {
+ self / rhs
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`.
+Wrapped division on unsigned types is just normal division.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
+Since, for the positive integers, all common
+definitions of division are equal, this
+is exactly equal to `self.wrapping_div(rhs)`.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
+ self / rhs
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) remainder. Computes `self % rhs`.
+Wrapped remainder calculation on unsigned types is
+just the regular remainder calculation.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_unstable(feature = "const_wrapping_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_rem(self, rhs: Self) -> Self {
+ self % rhs
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping Euclidean modulo. Computes `self.rem_euclid(rhs)`.
+Wrapped modulo calculation on unsigned types is
+just the regular remainder calculation.
+There's no way wrapping could ever happen.
+This function exists, so that all operations
+are accounted for in the wrapping operations.
+Since, for the positive integers, all common
+definitions of division are equal, this
+is exactly equal to `self.wrapping_rem(rhs)`.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
+ self % rhs
+ }
+ }
+
+ /// Wrapping (modular) negation. Computes `-self`,
+ /// wrapping around at the boundary of the type.
+ ///
+ /// Since unsigned types do not have negative equivalents
+ /// all applications of this function will wrap (except for `-0`).
+ /// For values smaller than the corresponding signed type's maximum
+ /// the result is the same as casting the corresponding signed value.
+ /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
+ /// `MAX` is the corresponding signed type's maximum.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `i8` is used here.
+ ///
+ /// ```
+ /// assert_eq!(100i8.wrapping_neg(), -100);
+ /// assert_eq!((-128i8).wrapping_neg(), -128);
+ /// ```
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[inline]
+ pub const fn wrapping_neg(self) -> Self {
+ self.overflowing_neg().0
+ }
+
+ doc_comment! {
+ concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`,
+where `mask` removes any high-order bits of `rhs` that
+would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-left; the
+RHS of a wrapping shift-left is restricted to the range
+of the type, rather than the bits shifted out of the LHS
+being returned to the other end. The primitive integer
+types all implement a [`rotate_left`](#method.rotate_left) function,
+which may be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);
+assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_shl(self, rhs: u32) -> Self {
+ // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+ // out of bounds
+ unsafe {
+ intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
+where `mask` removes any high-order bits of `rhs` that
+would cause the shift to exceed the bitwidth of the type.
+
+Note that this is *not* the same as a rotate-right; the
+RHS of a wrapping shift-right is restricted to the range
+of the type, rather than the bits shifted out of the LHS
+being returned to the other end. The primitive integer
+types all implement a [`rotate_right`](#method.rotate_right) function,
+which may be what you want instead.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);
+assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
+```"),
+ #[stable(feature = "num_wrapping", since = "1.2.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_shr(self, rhs: u32) -> Self {
+ // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+ // out of bounds
+ unsafe {
+ intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ }
+ }
+ }
+
+ doc_comment! {
+ concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);
+assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
+ if exp == 0 {
+ return 1;
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc.wrapping_mul(base);
+ }
+ exp /= 2;
+ base = base.wrapping_mul(base);
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ acc.wrapping_mul(base)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates `self` + `rhs`
+
+Returns a tuple of the addition along with a boolean indicating
+whether an arithmetic overflow would occur. If an overflow would
+have occurred then the wrapped value is returned.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
+assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates `self` - `rhs`
+
+Returns a tuple of the subtraction along with a boolean indicating
+whether an arithmetic overflow would occur. If an overflow would
+have occurred then the wrapped value is returned.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "
+assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));
+assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));",
+$EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+ }
+
+ /// Calculates the multiplication of `self` and `rhs`.
+ ///
+ /// Returns a tuple of the multiplication along with a boolean
+ /// indicating whether an arithmetic overflow would occur. If an
+ /// overflow would have occurred then the wrapped value is returned.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// Please note that this example is shared between integer types.
+ /// Which explains why `u32` is used here.
+ ///
+ /// ```
+ /// assert_eq!(5u32.overflowing_mul(2), (10, false));
+ /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
+ /// ```
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
+ (a as Self, b)
+ }
+
+ doc_comment! {
+ concat!("Calculates the divisor when `self` is divided by `rhs`.
+
+Returns a tuple of the divisor along with a boolean indicating
+whether an arithmetic overflow would occur. Note that for unsigned
+integers overflow never occurs, so the second value is always
+`false`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
+ (self / rhs, false)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
+
+Returns a tuple of the divisor along with a boolean indicating
+whether an arithmetic overflow would occur. Note that for unsigned
+integers overflow never occurs, so the second value is always
+`false`.
+Since, for the positive integers, all common
+definitions of division are equal, this
+is exactly equal to `self.overflowing_div(rhs)`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage
+
+```
+assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
+```"),
+ #[inline]
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
+ (self / rhs, false)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the remainder when `self` is divided by `rhs`.
+
+Returns a tuple of the remainder after dividing along with a boolean
+indicating whether an arithmetic overflow would occur. Note that for
+unsigned integers overflow never occurs, so the second value is
+always `false`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_unstable(feature = "const_overflowing_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
+ (self % rhs, false)
+ }
+ }
+
+ doc_comment! {
+ concat!("Calculates the remainder `self.rem_euclid(rhs)` as if by Euclidean division.
+
+Returns a tuple of the modulo after dividing along with a boolean
+indicating whether an arithmetic overflow would occur. Note that for
+unsigned integers overflow never occurs, so the second value is
+always `false`.
+Since, for the positive integers, all common
+definitions of division are equal, this operation
+is exactly equal to `self.overflowing_rem(rhs)`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage
+
+```
+assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
+```"),
+ #[inline]
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
+ (self % rhs, false)
+ }
+ }
+
+ doc_comment! {
+ concat!("Negates self in an overflowing fashion.
+
+Returns `!self + 1` using wrapping operations to return the value
+that represents the negation of this unsigned value. Note that for
+positive unsigned values overflow always occurs, but negating 0 does
+not overflow.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));
+assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT),
+", true));", $EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ pub const fn overflowing_neg(self) -> (Self, bool) {
+ ((!self).wrapping_add(1), self != 0)
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts self left by `rhs` bits.
+
+Returns a tuple of the shifted version of self along with a boolean
+indicating whether the shift value was larger than or equal to the
+number of bits. If the shift value is too large, then value is
+masked (N-1) where N is the number of bits, and this value is then
+used to perform the shift.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));
+assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Shifts self right by `rhs` bits.
+
+Returns a tuple of the shifted version of self along with a boolean
+indicating whether the shift value was larger than or equal to the
+number of bits. If the shift value is too large, then value is
+masked (N-1) where N is the number of bits, and this value is then
+used to perform the shift.
+
+# Examples
+
+Basic usage
+
+```
+", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));
+assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
+```"),
+ #[stable(feature = "wrapping", since = "1.7.0")]
+ #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
+ (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ }
+ }
+
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));
+assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
+```"),
+ #[stable(feature = "no_panic_pow", since = "1.34.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+ if exp == 0{
+ return (1,false);
+ }
+ let mut base = self;
+ let mut acc: Self = 1;
+ let mut overflown = false;
+ // Scratch space for storing results of overflowing_mul.
+ let mut r;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ r = acc.overflowing_mul(base);
+ acc = r.0;
+ overflown |= r.1;
+ }
+ exp /= 2;
+ r = base.overflowing_mul(base);
+ base = r.0;
+ overflown |= r.1;
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ r = acc.overflowing_mul(base);
+ r.1 |= overflown;
+
+ r
+ }
+ }
+
+ doc_comment! {
+ concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn pow(self, mut exp: u32) -> Self {
+ if exp == 0 {
+ return 1;
+ }
+ let mut base = self;
+ let mut acc = 1;
+
+ while exp > 1 {
+ if (exp & 1) == 1 {
+ acc = acc * base;
+ }
+ exp /= 2;
+ base = base * base;
+ }
+
+ // since exp!=0, finally the exp must be 1.
+ // Deal with the final bit of the exponent separately, since
+ // squaring the base afterwards is not necessary and may cause a
+ // needless overflow.
+ acc * base
+ }
+ }
+
+ doc_comment! {
+ concat!("Performs Euclidean division.
+
+Since, for the positive integers, all common
+definitions of division are equal, this
+is exactly equal to `self / rhs`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn div_euclid(self, rhs: Self) -> Self {
+ self / rhs
+ }
+ }
+
+
+ doc_comment! {
+ concat!("Calculates the least remainder of `self (mod rhs)`.
+
+Since, for the positive integers, all common
+definitions of division are equal, this
+is exactly equal to `self % rhs`.
+
+# Panics
+
+This function will panic if `rhs` is 0.
+
+# Examples
+
+Basic usage:
+
+```
+assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type
+```"),
+ #[stable(feature = "euclidean_division", since = "1.38.0")]
+ #[rustc_const_unstable(feature = "const_euclidean_int_methods", issue = "53718")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn rem_euclid(self, rhs: Self) -> Self {
+ self % rhs
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns `true` if and only if `self == 2^k` for some `k`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert!(16", stringify!($SelfT), ".is_power_of_two());
+assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")]
+ #[inline]
+ pub const fn is_power_of_two(self) -> bool {
+ self.count_ones() == 1
+ }
+ }
+
+ // Returns one less than next power of two.
+ // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8)
+ //
+ // 8u8.one_less_than_next_power_of_two() == 7
+ // 6u8.one_less_than_next_power_of_two() == 7
+ //
+ // This method cannot overflow, as in the `next_power_of_two`
+ // overflow cases it instead ends up returning the maximum value
+ // of the type, and can return 0 for 0.
+ #[inline]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ const fn one_less_than_next_power_of_two(self) -> Self {
+ if self <= 1 { return 0; }
+
+ let p = self - 1;
+ // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
+ // That means the shift is always in-bounds, and some processors
+ // (such as intel pre-haswell) have more efficient ctlz
+ // intrinsics when the argument is non-zero.
+ let z = unsafe { intrinsics::ctlz_nonzero(p) };
+ <$SelfT>::MAX >> z
+ }
+
+ doc_comment! {
+ concat!("Returns the smallest power of two greater than or equal to `self`.
+
+When return value overflows (i.e., `self > (1 << (N-1))` for type
+`uN`), it panics in debug mode and return value is wrapped to 0 in
+release mode (the only situation in which method can return 0).
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);
+assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
+```"),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ pub const fn next_power_of_two(self) -> Self {
+ self.one_less_than_next_power_of_two() + 1
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the smallest power of two greater than or equal to `n`. If
+the next power of two is greater than the type's maximum value,
+`None` is returned, otherwise the power of two is wrapped in `Some`.
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "assert_eq!(2", stringify!($SelfT),
+".checked_next_power_of_two(), Some(2));
+assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4));
+assert_eq!(", stringify!($SelfT), "::MAX.checked_next_power_of_two(), None);",
+$EndFeature, "
+```"),
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ pub const fn checked_next_power_of_two(self) -> Option<Self> {
+ self.one_less_than_next_power_of_two().checked_add(1)
+ }
+ }
+
+ doc_comment! {
+ concat!("Returns the smallest power of two greater than or equal to `n`. If
+the next power of two is greater than the type's maximum value,
+the return value is wrapped to `0`.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(wrapping_next_power_of_two)]
+", $Feature, "
+assert_eq!(2", stringify!($SelfT), ".wrapping_next_power_of_two(), 2);
+assert_eq!(3", stringify!($SelfT), ".wrapping_next_power_of_two(), 4);
+assert_eq!(", stringify!($SelfT), "::MAX.wrapping_next_power_of_two(), 0);",
+$EndFeature, "
+```"),
+ #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
+ reason = "needs decision on wrapping behaviour")]
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
+ pub const fn wrapping_next_power_of_two(self) -> Self {
+ self.one_less_than_next_power_of_two().wrapping_add(1)
+ }
+ }
+
+ doc_comment! {
+ concat!("Return the memory representation of this integer as a byte array in
+big-endian (network) byte order.
+",
+$to_xe_bytes_doc,
+"
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
+assert_eq!(bytes, ", $be_bytes, ");
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ self.to_be().to_ne_bytes()
+ }
+ }
+
+ doc_comment! {
+ concat!("Return the memory representation of this integer as a byte array in
+little-endian byte order.
+",
+$to_xe_bytes_doc,
+"
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
+assert_eq!(bytes, ", $le_bytes, ");
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ self.to_le().to_ne_bytes()
+ }
+ }
+
+ doc_comment! {
+ concat!("
+Return the memory representation of this integer as a byte array in
+native byte order.
+
+As the target platform's native endianness is used, portable code
+should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
+instead.
+",
+$to_xe_bytes_doc,
+"
+[`to_be_bytes`]: #method.to_be_bytes
+[`to_le_bytes`]: #method.to_le_bytes
+
+# Examples
+
+```
+let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
+assert_eq!(
+ bytes,
+ if cfg!(target_endian = \"big\") {
+ ", $be_bytes, "
+ } else {
+ ", $le_bytes, "
+ }
+);
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ // SAFETY: const sound because integers are plain old datatypes so we can always
+ // transmute them to arrays of bytes
+ #[allow_internal_unstable(const_fn_transmute)]
+ #[inline]
+ pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+ // SAFETY: integers are plain old datatypes so we can always transmute them to
+ // arrays of bytes
+ unsafe { mem::transmute(self) }
+ }
+ }
+
+ doc_comment! {
+ concat!("Create a native endian integer value from its representation
+as a byte array in big endian.
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_be(Self::from_ne_bytes(bytes))
+ }
+ }
+
+ doc_comment! {
+ concat!("
+Create a native endian integer value from its representation
+as a byte array in little endian.
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ #[inline]
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+ }
+
+ doc_comment! {
+ concat!("Create a native endian integer value from its memory representation
+as a byte array in native endianness.
+
+As the target platform's native endianness is used, portable code
+likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
+appropriate instead.
+
+[`from_be_bytes`]: #method.from_be_bytes
+[`from_le_bytes`]: #method.from_le_bytes
+",
+$from_xe_bytes_doc,
+"
+# Examples
+
+```
+let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
+ ", $be_bytes, "
+} else {
+ ", $le_bytes, "
+});
+assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+use std::convert::TryInto;
+
+fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+ let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+ *input = rest;
+ ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
+}
+```"),
+ #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+ // SAFETY: const sound because integers are plain old datatypes so we can always
+ // transmute to them
+ #[allow_internal_unstable(const_fn_transmute)]
+ #[inline]
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ // SAFETY: integers are plain old datatypes so we can always transmute to them
+ unsafe { mem::transmute(bytes) }
+ }
+ }
+
+ doc_comment! {
+ concat!("**This method is soft-deprecated.**
+
+Although using it won’t cause compilation warning,
+new code should use [`", stringify!($SelfT), "::MIN", "`](#associatedconstant.MIN) instead.
+
+Returns the smallest value that can be represented by this integer type."),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_promotable]
+ #[inline(always)]
+ #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
+ pub const fn min_value() -> Self { Self::MIN }
+ }
+
+ doc_comment! {
+ concat!("**This method is soft-deprecated.**
+
+Although using it won’t cause compilation warning,
+new code should use [`", stringify!($SelfT), "::MAX", "`](#associatedconstant.MAX) instead.
+
+Returns the largest value that can be represented by this integer type."),
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_promotable]
+ #[inline(always)]
+ #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")]
+ pub const fn max_value() -> Self { Self::MAX }
+ }
+ }
+}
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index f6acb8f..5324dfd 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -1,6 +1,83 @@
-use super::Wrapping;
+//! Definitions of `Wrapping<T>`.
-use crate::ops::*;
+use crate::fmt;
+use crate::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
+use crate::ops::{BitXor, BitXorAssign, Div, DivAssign};
+use crate::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign};
+use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
+
+/// Provides intentionally-wrapped arithmetic on `T`.
+///
+/// Operations like `+` on `u32` values are intended to never overflow,
+/// and in some debug configurations overflow is detected and results
+/// in a panic. While most arithmetic falls into this category, some
+/// code explicitly expects and relies upon modular arithmetic (e.g.,
+/// hashing).
+///
+/// Wrapping arithmetic can be achieved either through methods like
+/// `wrapping_add`, or through the `Wrapping<T>` type, which says that
+/// all standard arithmetic operations on the underlying value are
+/// intended to have wrapping semantics.
+///
+/// The underlying value can be retrieved through the `.0` index of the
+/// `Wrapping` tuple.
+///
+/// # Examples
+///
+/// ```
+/// use std::num::Wrapping;
+///
+/// let zero = Wrapping(0u32);
+/// let one = Wrapping(1u32);
+///
+/// assert_eq!(u32::MAX, (zero - one).0);
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
+#[repr(transparent)]
+pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: fmt::Debug> fmt::Debug for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[stable(feature = "wrapping_display", since = "1.10.0")]
+impl<T: fmt::Display> fmt::Display for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[stable(feature = "wrapping_fmt", since = "1.11.0")]
+impl<T: fmt::Binary> fmt::Binary for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[stable(feature = "wrapping_fmt", since = "1.11.0")]
+impl<T: fmt::Octal> fmt::Octal for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[stable(feature = "wrapping_fmt", since = "1.11.0")]
+impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[stable(feature = "wrapping_fmt", since = "1.11.0")]
+impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
#[allow(unused_macros)]
macro_rules! sh_impl_signed {
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 622a138..19f86ce 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -78,6 +78,12 @@
type Output;
/// Performs the `+` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 + 1, 13);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn add(self, rhs: Rhs) -> Self::Output;
@@ -122,10 +128,10 @@
/// }
///
/// impl Sub for Point {
-/// type Output = Point;
+/// type Output = Self;
///
-/// fn sub(self, other: Point) -> Point {
-/// Point {
+/// fn sub(self, other: Self) -> Self::Output {
+/// Self {
/// x: self.x - other.x,
/// y: self.y - other.y,
/// }
@@ -178,6 +184,12 @@
type Output;
/// Performs the `-` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 - 1, 11);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn sub(self, rhs: Rhs) -> Self::Output;
@@ -229,7 +241,7 @@
/// // Reduce to lowest terms by dividing by the greatest common
/// // divisor.
/// let gcd = gcd(numerator, denominator);
-/// Rational {
+/// Self {
/// numerator: numerator / gcd,
/// denominator: denominator / gcd,
/// }
@@ -243,7 +255,7 @@
/// fn mul(self, rhs: Self) -> Self {
/// let numerator = self.numerator * rhs.numerator;
/// let denominator = self.denominator * rhs.denominator;
-/// Rational::new(numerator, denominator)
+/// Self::new(numerator, denominator)
/// }
/// }
///
@@ -279,7 +291,7 @@
/// type Output = Self;
///
/// fn mul(self, rhs: Scalar) -> Self::Output {
-/// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
+/// Self { value: self.value.iter().map(|v| v * rhs.value).collect() }
/// }
/// }
///
@@ -300,6 +312,12 @@
type Output;
/// Performs the `*` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 * 2, 24);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn mul(self, rhs: Rhs) -> Self::Output;
@@ -351,7 +369,7 @@
/// // Reduce to lowest terms by dividing by the greatest common
/// // divisor.
/// let gcd = gcd(numerator, denominator);
-/// Rational {
+/// Self {
/// numerator: numerator / gcd,
/// denominator: denominator / gcd,
/// }
@@ -369,7 +387,7 @@
///
/// let numerator = self.numerator * rhs.denominator;
/// let denominator = self.denominator * rhs.numerator;
-/// Rational::new(numerator, denominator)
+/// Self::new(numerator, denominator)
/// }
/// }
///
@@ -405,7 +423,7 @@
/// type Output = Self;
///
/// fn div(self, rhs: Scalar) -> Self::Output {
-/// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
+/// Self { value: self.value.iter().map(|v| v / rhs.value).collect() }
/// }
/// }
///
@@ -426,6 +444,12 @@
type Output;
/// Performs the `/` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 / 2, 6);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn div(self, rhs: Rhs) -> Self::Output;
@@ -491,7 +515,7 @@
/// let len = self.slice.len();
/// let rem = len % modulus;
/// let start = len - rem;
-/// SplitSlice {slice: &self.slice[start..]}
+/// Self {slice: &self.slice[start..]}
/// }
/// }
///
@@ -513,6 +537,12 @@
type Output;
/// Performs the `%` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 % 10, 2);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn rem(self, rhs: Rhs) -> Self::Output;
@@ -585,7 +615,7 @@
/// }
///
/// impl Neg for Sign {
-/// type Output = Sign;
+/// type Output = Self;
///
/// fn neg(self) -> Self::Output {
/// match self {
@@ -612,6 +642,13 @@
type Output;
/// Performs the unary `-` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let x: i32 = 12;
+ /// assert_eq!(-x, -12);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn neg(self) -> Self::Output;
@@ -673,6 +710,14 @@
#[doc(alias = "+=")]
pub trait AddAssign<Rhs = Self> {
/// Performs the `+=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x += 1;
+ /// assert_eq!(x, 13);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn add_assign(&mut self, rhs: Rhs);
}
@@ -731,6 +776,14 @@
#[doc(alias = "-=")]
pub trait SubAssign<Rhs = Self> {
/// Performs the `-=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x -= 1;
+ /// assert_eq!(x, 11);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn sub_assign(&mut self, rhs: Rhs);
}
@@ -780,6 +833,14 @@
#[doc(alias = "*=")]
pub trait MulAssign<Rhs = Self> {
/// Performs the `*=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x *= 2;
+ /// assert_eq!(x, 24);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn mul_assign(&mut self, rhs: Rhs);
}
@@ -829,6 +890,14 @@
#[doc(alias = "/=")]
pub trait DivAssign<Rhs = Self> {
/// Performs the `/=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x /= 2;
+ /// assert_eq!(x, 6);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn div_assign(&mut self, rhs: Rhs);
}
@@ -881,6 +950,14 @@
#[doc(alias = "%=")]
pub trait RemAssign<Rhs = Self> {
/// Performs the `%=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x %= 10;
+ /// assert_eq!(x, 2);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn rem_assign(&mut self, rhs: Rhs);
}
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
index bcfff4a..6120da5 100644
--- a/library/core/src/ops/bit.rs
+++ b/library/core/src/ops/bit.rs
@@ -15,7 +15,7 @@
/// }
///
/// impl Not for Answer {
-/// type Output = Answer;
+/// type Output = Self;
///
/// fn not(self) -> Self::Output {
/// match self {
@@ -36,6 +36,15 @@
type Output;
/// Performs the unary `!` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(!true, false);
+ /// assert_eq!(!false, true);
+ /// assert_eq!(!1u8, 254);
+ /// assert_eq!(!0u8, 255);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn not(self) -> Self::Output;
@@ -76,7 +85,7 @@
///
/// // rhs is the "right-hand side" of the expression `a & b`
/// fn bitand(self, rhs: Self) -> Self::Output {
-/// Scalar(self.0 & rhs.0)
+/// Self(self.0 & rhs.0)
/// }
/// }
///
@@ -97,10 +106,13 @@
/// impl BitAnd for BooleanVector {
/// type Output = Self;
///
-/// fn bitand(self, BooleanVector(rhs): Self) -> Self::Output {
-/// let BooleanVector(lhs) = self;
+/// fn bitand(self, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
-/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect())
+/// Self(lhs.iter()
+/// .zip(rhs.iter())
+/// .map(|(x, y)| *x && *y)
+/// .collect())
/// }
/// }
///
@@ -122,6 +134,15 @@
type Output;
/// Performs the `&` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true & false, false);
+ /// assert_eq!(true & true, true);
+ /// assert_eq!(5u8 & 1u8, 1);
+ /// assert_eq!(5u8 & 2u8, 0);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn bitand(self, rhs: Rhs) -> Self::Output;
@@ -161,8 +182,8 @@
/// type Output = Self;
///
/// // rhs is the "right-hand side" of the expression `a | b`
-/// fn bitor(self, rhs: Self) -> Self {
-/// Scalar(self.0 | rhs.0)
+/// fn bitor(self, rhs: Self) -> Self::Output {
+/// Self(self.0 | rhs.0)
/// }
/// }
///
@@ -183,10 +204,10 @@
/// impl BitOr for BooleanVector {
/// type Output = Self;
///
-/// fn bitor(self, BooleanVector(rhs): Self) -> Self::Output {
-/// let BooleanVector(lhs) = self;
+/// fn bitor(self, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
-/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
+/// Self(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
/// }
/// }
///
@@ -208,6 +229,15 @@
type Output;
/// Performs the `|` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true | false, true);
+ /// assert_eq!(false | false, false);
+ /// assert_eq!(5u8 | 1u8, 5);
+ /// assert_eq!(5u8 | 2u8, 7);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn bitor(self, rhs: Rhs) -> Self::Output;
@@ -248,7 +278,7 @@
///
/// // rhs is the "right-hand side" of the expression `a ^ b`
/// fn bitxor(self, rhs: Self) -> Self::Output {
-/// Scalar(self.0 ^ rhs.0)
+/// Self(self.0 ^ rhs.0)
/// }
/// }
///
@@ -269,13 +299,13 @@
/// impl BitXor for BooleanVector {
/// type Output = Self;
///
-/// fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output {
-/// let BooleanVector(lhs) = self;
+/// fn bitxor(self, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
-/// BooleanVector(lhs.iter()
-/// .zip(rhs.iter())
-/// .map(|(x, y)| (*x || *y) && !(*x && *y))
-/// .collect())
+/// Self(lhs.iter()
+/// .zip(rhs.iter())
+/// .map(|(x, y)| (*x || *y) && !(*x && *y))
+/// .collect())
/// }
/// }
///
@@ -297,6 +327,15 @@
type Output;
/// Performs the `^` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true ^ false, true);
+ /// assert_eq!(true ^ true, false);
+ /// assert_eq!(5u8 ^ 1u8, 4);
+ /// assert_eq!(5u8 ^ 2u8, 7);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn bitxor(self, rhs: Rhs) -> Self::Output;
@@ -339,9 +378,9 @@
/// impl Shl<Scalar> for Scalar {
/// type Output = Self;
///
-/// fn shl(self, Scalar(rhs): Self) -> Scalar {
-/// let Scalar(lhs) = self;
-/// Scalar(lhs << rhs)
+/// fn shl(self, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// Self(lhs << rhs)
/// }
/// }
///
@@ -364,10 +403,10 @@
/// fn shl(self, rhs: usize) -> Self::Output {
/// // Rotate the vector by `rhs` places.
/// let (a, b) = self.vec.split_at(rhs);
-/// let mut spun_vector: Vec<T> = vec![];
+/// let mut spun_vector = vec![];
/// spun_vector.extend_from_slice(b);
/// spun_vector.extend_from_slice(a);
-/// SpinVector { vec: spun_vector }
+/// Self { vec: spun_vector }
/// }
/// }
///
@@ -387,6 +426,13 @@
type Output;
/// Performs the `<<` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(5u8 << 1, 10);
+ /// assert_eq!(1u8 << 1, 2);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn shl(self, rhs: Rhs) -> Self::Output;
@@ -450,9 +496,9 @@
/// impl Shr<Scalar> for Scalar {
/// type Output = Self;
///
-/// fn shr(self, Scalar(rhs): Self) -> Scalar {
-/// let Scalar(lhs) = self;
-/// Scalar(lhs >> rhs)
+/// fn shr(self, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// Self(lhs >> rhs)
/// }
/// }
///
@@ -475,10 +521,10 @@
/// fn shr(self, rhs: usize) -> Self::Output {
/// // Rotate the vector by `rhs` places.
/// let (a, b) = self.vec.split_at(self.vec.len() - rhs);
-/// let mut spun_vector: Vec<T> = vec![];
+/// let mut spun_vector = vec![];
/// spun_vector.extend_from_slice(b);
/// spun_vector.extend_from_slice(a);
-/// SpinVector { vec: spun_vector }
+/// Self { vec: spun_vector }
/// }
/// }
///
@@ -498,6 +544,13 @@
type Output;
/// Performs the `>>` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(5u8 >> 1, 2);
+ /// assert_eq!(2u8 >> 1, 1);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn shr(self, rhs: Rhs) -> Self::Output;
@@ -556,7 +609,7 @@
/// impl BitAndAssign for Scalar {
/// // rhs is the "right-hand side" of the expression `a &= b`
/// fn bitand_assign(&mut self, rhs: Self) {
-/// *self = Scalar(self.0 & rhs.0)
+/// *self = Self(self.0 & rhs.0)
/// }
/// }
///
@@ -590,11 +643,11 @@
/// // `rhs` is the "right-hand side" of the expression `a &= b`.
/// fn bitand_assign(&mut self, rhs: Self) {
/// assert_eq!(self.0.len(), rhs.0.len());
-/// *self = BooleanVector(self.0
-/// .iter()
-/// .zip(rhs.0.iter())
-/// .map(|(x, y)| *x && *y)
-/// .collect());
+/// *self = Self(self.0
+/// .iter()
+/// .zip(rhs.0.iter())
+/// .map(|(x, y)| *x && *y)
+/// .collect());
/// }
/// }
///
@@ -612,6 +665,26 @@
)]
pub trait BitAndAssign<Rhs = Self> {
/// Performs the `&=` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x &= false;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x = true;
+ /// x &= true;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x: u8 = 5;
+ /// x &= 1;
+ /// assert_eq!(x, 1);
+ ///
+ /// let mut x: u8 = 5;
+ /// x &= 2;
+ /// assert_eq!(x, 0);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitand_assign(&mut self, rhs: Rhs);
}
@@ -663,6 +736,26 @@
)]
pub trait BitOrAssign<Rhs = Self> {
/// Performs the `|=` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x |= false;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x = false;
+ /// x |= false;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x: u8 = 5;
+ /// x |= 1;
+ /// assert_eq!(x, 5);
+ ///
+ /// let mut x: u8 = 5;
+ /// x |= 2;
+ /// assert_eq!(x, 7);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitor_assign(&mut self, rhs: Rhs);
}
@@ -714,6 +807,26 @@
)]
pub trait BitXorAssign<Rhs = Self> {
/// Performs the `^=` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x ^= false;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x = true;
+ /// x ^= true;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x: u8 = 5;
+ /// x ^= 1;
+ /// assert_eq!(x, 4);
+ ///
+ /// let mut x: u8 = 5;
+ /// x ^= 2;
+ /// assert_eq!(x, 7);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn bitxor_assign(&mut self, rhs: Rhs);
}
@@ -763,6 +876,18 @@
)]
pub trait ShlAssign<Rhs = Self> {
/// Performs the `<<=` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x: u8 = 5;
+ /// x <<= 1;
+ /// assert_eq!(x, 10);
+ ///
+ /// let mut x: u8 = 1;
+ /// x <<= 1;
+ /// assert_eq!(x, 2);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn shl_assign(&mut self, rhs: Rhs);
}
@@ -833,6 +958,18 @@
)]
pub trait ShrAssign<Rhs = Self> {
/// Performs the `>>=` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x: u8 = 5;
+ /// x >>= 1;
+ /// assert_eq!(x, 2);
+ ///
+ /// let mut x: u8 = 2;
+ /// x >>= 1;
+ /// assert_eq!(x, 1);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn shr_assign(&mut self, rhs: Rhs);
}
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
new file mode 100644
index 0000000..5ede1ba
--- /dev/null
+++ b/library/core/src/ops/control_flow.rs
@@ -0,0 +1,124 @@
+use crate::ops::Try;
+
+/// Used to make try_fold closures more like normal loops
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum ControlFlow<B, C = ()> {
+ /// Continue in the loop, using the given value for the next iteration
+ Continue(C),
+ /// Exit the loop, yielding the given value
+ Break(B),
+}
+
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+impl<B, C> Try for ControlFlow<B, C> {
+ type Ok = C;
+ type Error = B;
+ #[inline]
+ fn into_result(self) -> Result<Self::Ok, Self::Error> {
+ match self {
+ ControlFlow::Continue(y) => Ok(y),
+ ControlFlow::Break(x) => Err(x),
+ }
+ }
+ #[inline]
+ fn from_error(v: Self::Error) -> Self {
+ ControlFlow::Break(v)
+ }
+ #[inline]
+ fn from_ok(v: Self::Ok) -> Self {
+ ControlFlow::Continue(v)
+ }
+}
+
+impl<B, C> ControlFlow<B, C> {
+ /// Returns `true` if this is a `Break` variant.
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn is_break(&self) -> bool {
+ matches!(*self, ControlFlow::Break(_))
+ }
+
+ /// Returns `true` if this is a `Continue` variant.
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn is_continue(&self) -> bool {
+ matches!(*self, ControlFlow::Continue(_))
+ }
+
+ /// Converts the `ControlFlow` into an `Option` which is `Some` if the
+ /// `ControlFlow` was `Break` and `None` otherwise.
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn break_value(self) -> Option<B> {
+ match self {
+ ControlFlow::Continue(..) => None,
+ ControlFlow::Break(x) => Some(x),
+ }
+ }
+}
+
+impl<R: Try> ControlFlow<R, R::Ok> {
+ /// Create a `ControlFlow` from any type implementing `Try`.
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ #[inline]
+ pub fn from_try(r: R) -> Self {
+ match Try::into_result(r) {
+ Ok(v) => ControlFlow::Continue(v),
+ Err(v) => ControlFlow::Break(Try::from_error(v)),
+ }
+ }
+
+ /// Convert a `ControlFlow` into any type implementing `Try`;
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ #[inline]
+ pub fn into_try(self) -> R {
+ match self {
+ ControlFlow::Continue(v) => Try::from_ok(v),
+ ControlFlow::Break(v) => v,
+ }
+ }
+}
+
+impl<B> ControlFlow<B, ()> {
+ /// It's frequently the case that there's no value needed with `Continue`,
+ /// so this provides a way to avoid typing `(())`, if you prefer it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// let mut partial_sum = 0;
+ /// let last_used = (1..10).chain(20..25).try_for_each(|x| {
+ /// partial_sum += x;
+ /// if partial_sum > 100 { ControlFlow::Break(x) }
+ /// else { ControlFlow::CONTINUE }
+ /// });
+ /// assert_eq!(last_used.break_value(), Some(22));
+ /// ```
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub const CONTINUE: Self = ControlFlow::Continue(());
+}
+
+impl<C> ControlFlow<(), C> {
+ /// APIs like `try_for_each` don't need values with `Break`,
+ /// so this provides a way to avoid typing `(())`, if you prefer it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// let mut partial_sum = 0;
+ /// (1..10).chain(20..25).try_for_each(|x| {
+ /// if partial_sum > 100 { ControlFlow::BREAK }
+ /// else { partial_sum += x; ControlFlow::CONTINUE }
+ /// });
+ /// assert_eq!(partial_sum, 108);
+ /// ```
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub const BREAK: Self = ControlFlow::Break(());
+}
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index d6c097e..245152e 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -63,11 +63,13 @@
pub trait Deref {
/// The resulting type after dereferencing.
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "deref_target"]
type Target: ?Sized;
/// Dereferences the value.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "deref_method"]
fn deref(&self) -> &Self::Target;
}
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index c19bd6e..354ad6b 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -49,18 +49,18 @@
//! }
//!
//! impl Add for Point {
-//! type Output = Point;
+//! type Output = Self;
//!
-//! fn add(self, other: Point) -> Point {
-//! Point {x: self.x + other.x, y: self.y + other.y}
+//! fn add(self, other: Self) -> Self {
+//! Self {x: self.x + other.x, y: self.y + other.y}
//! }
//! }
//!
//! impl Sub for Point {
-//! type Output = Point;
+//! type Output = Self;
//!
-//! fn sub(self, other: Point) -> Point {
-//! Point {x: self.x - other.x, y: self.y - other.y}
+//! fn sub(self, other: Self) -> Self {
+//! Self {x: self.x - other.x, y: self.y - other.y}
//! }
//! }
//!
@@ -140,6 +140,7 @@
mod arith;
mod bit;
+mod control_flow;
mod deref;
mod drop;
mod function;
@@ -191,3 +192,6 @@
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
pub use self::unsize::DispatchFromDyn;
+
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+pub use self::control_flow::ControlFlow;
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index d108298..2eaf760 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -36,7 +36,7 @@
/// ```
///
/// [slicing index]: crate::slice::SliceIndex
-#[cfg_attr(not(bootstrap), lang = "RangeFull")]
+#[lang = "RangeFull"]
#[doc(alias = "..")]
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -69,7 +69,7 @@
/// assert_eq!(arr[1.. 3], [ 1,2 ]); // Range
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
-#[cfg_attr(not(bootstrap), lang = "Range")]
+#[lang = "Range"]
#[doc(alias = "..")]
#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
@@ -172,7 +172,7 @@
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
-#[cfg_attr(not(bootstrap), lang = "RangeFrom")]
+#[lang = "RangeFrom"]
#[doc(alias = "..")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
@@ -253,7 +253,7 @@
/// ```
///
/// [slicing index]: crate::slice::SliceIndex
-#[cfg_attr(not(bootstrap), lang = "RangeTo")]
+#[lang = "RangeTo"]
#[doc(alias = "..")]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -322,7 +322,7 @@
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
/// ```
-#[cfg_attr(not(bootstrap), lang = "RangeInclusive")]
+#[lang = "RangeInclusive"]
#[doc(alias = "..=")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "inclusive_range", since = "1.26.0")]
@@ -354,7 +354,7 @@
///
/// assert_eq!(3..=5, RangeInclusive::new(3, 5));
/// ```
- #[cfg_attr(not(bootstrap), lang = "range_inclusive_new")]
+ #[lang = "range_inclusive_new"]
#[stable(feature = "inclusive_range_methods", since = "1.27.0")]
#[inline]
#[rustc_promotable]
@@ -543,7 +543,7 @@
/// ```
///
/// [slicing index]: crate::slice::SliceIndex
-#[cfg_attr(not(bootstrap), lang = "RangeToInclusive")]
+#[lang = "RangeToInclusive"]
#[doc(alias = "..=")]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[stable(feature = "inclusive_range", since = "1.26.0")]
diff --git a/library/core/src/ops/try.rs b/library/core/src/ops/try.rs
index e6b05cc..3bede56 100644
--- a/library/core/src/ops/try.rs
+++ b/library/core/src/ops/try.rs
@@ -43,19 +43,19 @@
/// in the return type of the enclosing scope (which must itself implement
/// `Try`). Specifically, the value `X::from_error(From::from(e))`
/// is returned, where `X` is the return type of the enclosing function.
- #[cfg_attr(not(bootstrap), lang = "into_result")]
+ #[lang = "into_result"]
#[unstable(feature = "try_trait", issue = "42327")]
fn into_result(self) -> Result<Self::Ok, Self::Error>;
/// Wrap an error value to construct the composite result. For example,
/// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
- #[cfg_attr(not(bootstrap), lang = "from_error")]
+ #[lang = "from_error"]
#[unstable(feature = "try_trait", issue = "42327")]
fn from_error(v: Self::Error) -> Self;
/// Wrap an OK value to construct the composite result. For example,
/// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
- #[cfg_attr(not(bootstrap), lang = "from_ok")]
+ #[lang = "from_ok"]
#[unstable(feature = "try_trait", issue = "42327")]
fn from_ok(v: Self::Ok) -> Self;
}
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index b6aa2c6..0cfb4af 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -70,10 +70,23 @@
//! }
//! ```
//!
-//! This usage of [`Option`] to create safe nullable pointers is so
-//! common that Rust does special optimizations to make the
-//! representation of [`Option`]`<`[`Box<T>`]`>` a single pointer. Optional pointers
-//! in Rust are stored as efficiently as any other pointer type.
+//! # Representation
+//!
+//! Rust guarantees to optimize the following types `T` such that
+//! [`Option<T>`] has the same size as `T`:
+//!
+//! * [`Box<U>`]
+//! * `&U`
+//! * `&mut U`
+//! * `fn`, `extern "C" fn`
+//! * [`num::NonZero*`]
+//! * [`ptr::NonNull<U>`]
+//! * `#[repr(transparent)]` struct around one of the types in this list.
+//!
+//! It is further guaranteed that, for the cases above, one can
+//! [`mem::transmute`] from all valid values of `T` to `Option<T>` and
+//! from `Some::<T>(_)` to `T` (but transmuting `None::<T>` to `T`
+//! is undefined behaviour).
//!
//! # Examples
//!
@@ -144,11 +157,11 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Option<T> {
/// No value
- #[cfg_attr(not(bootstrap), lang = "None")]
+ #[lang = "None"]
#[stable(feature = "rust1", since = "1.0.0")]
None,
/// Some value `T`
- #[cfg_attr(not(bootstrap), lang = "Some")]
+ #[lang = "Some"]
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}
@@ -175,7 +188,7 @@
/// ```
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
#[inline]
- #[rustc_const_unstable(feature = "const_option", issue = "67441")]
+ #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_some(&self) -> bool {
matches!(*self, Some(_))
@@ -195,7 +208,7 @@
#[must_use = "if you intended to assert that this doesn't have a value, consider \
`.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"]
#[inline]
- #[rustc_const_unstable(feature = "const_option", issue = "67441")]
+ #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_none(&self) -> bool {
!self.is_some()
@@ -254,7 +267,7 @@
/// println!("still can print text: {:?}", text);
/// ```
#[inline]
- #[rustc_const_unstable(feature = "const_option", issue = "67441")]
+ #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn as_ref(&self) -> Option<&T> {
match *self {
@@ -1502,8 +1515,6 @@
/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
///
/// This `struct` is created by the [`Option::into_iter`] function.
-///
-/// [`Option::into_iter`]: enum.Option.html#method.into_iter
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<A> {
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index 316ecaf..34a974b 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -92,8 +92,6 @@
/// If the `panic!` macro from the `core` crate (not from `std`)
/// was used with a formatting string and some additional arguments,
/// returns that message ready to be used for example with [`fmt::write`]
- ///
- /// [`fmt::write`]: ../fmt/fn.write.html
#[unstable(feature = "panic_info_message", issue = "66745")]
pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
self.message
@@ -105,8 +103,6 @@
/// This method will currently always return [`Some`], but this may change
/// in future versions.
///
- /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
- ///
/// # Examples
///
/// ```should_panic
@@ -153,10 +149,7 @@
/// A struct containing information about the location of a panic.
///
-/// This structure is created by the [`location`] method of [`PanicInfo`].
-///
-/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
-/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
+/// This structure is created by [`PanicInfo::location()`].
///
/// # Examples
///
@@ -232,7 +225,7 @@
/// assert_ne!(this_location.column(), another_location.column());
/// ```
#[stable(feature = "track_caller", since = "1.46.0")]
- #[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
+ #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
#[track_caller]
pub const fn caller() -> &'static Location<'static> {
crate::intrinsics::caller_location()
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 290aa79..b73cd04 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -471,10 +471,11 @@
///
/// Unlike `Pin::new_unchecked`, this method is safe because the pointer
/// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees.
- #[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
- pub fn new(pointer: P) -> Pin<P> {
- // Safety: the value pointed to is `Unpin`, and so has no requirements
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin", since = "1.33.0")]
+ pub const fn new(pointer: P) -> Pin<P> {
+ // SAFETY: the value pointed to is `Unpin`, and so has no requirements
// around pinning.
unsafe { Pin::new_unchecked(pointer) }
}
@@ -483,9 +484,10 @@
///
/// This requires that the data inside this `Pin` is [`Unpin`] so that we
/// can ignore the pinning invariants when unwrapping it.
- #[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)]
- pub fn into_inner(pin: Pin<P>) -> P {
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin_into_inner", since = "1.39.0")]
+ pub const fn into_inner(pin: Pin<P>) -> P {
pin.pointer
}
}
@@ -541,7 +543,7 @@
/// use std::pin::Pin;
///
/// fn move_pinned_rc<T>(mut x: Rc<T>) {
- /// let pinned = unsafe { Pin::new_unchecked(x.clone()) };
+ /// let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
/// {
/// let p: Pin<&T> = pinned.as_ref();
/// // This should mean the pointee can never move again.
@@ -555,10 +557,11 @@
/// ```
///
/// [`mem::swap`]: crate::mem::swap
- #[cfg_attr(not(bootstrap), lang = "new_unchecked")]
- #[stable(feature = "pin", since = "1.33.0")]
+ #[lang = "new_unchecked"]
#[inline(always)]
- pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin", since = "1.33.0")]
+ pub const unsafe fn new_unchecked(pointer: P) -> Pin<P> {
Pin { pointer }
}
@@ -589,9 +592,10 @@
///
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
/// instead.
- #[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)]
- pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin_into_inner", since = "1.39.0")]
+ pub const unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
pin.pointer
}
}
@@ -661,7 +665,7 @@
/// because it is one of the fields of that value), and also that you do
/// not move out of the argument you receive to the interior function.
///
- /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
+ /// [`pin` module]: self#projections-and-structural-pinning
#[stable(feature = "pin", since = "1.33.0")]
pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>
where
@@ -692,19 +696,21 @@
/// the `Pin` itself. This method allows turning the `Pin` into a reference
/// with the same lifetime as the original `Pin`.
///
- /// ["pinning projections"]: ../../std/pin/index.html#projections-and-structural-pinning
- #[stable(feature = "pin", since = "1.33.0")]
+ /// ["pinning projections"]: self#projections-and-structural-pinning
#[inline(always)]
- pub fn get_ref(self) -> &'a T {
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin", since = "1.33.0")]
+ pub const fn get_ref(self) -> &'a T {
self.pointer
}
}
impl<'a, T: ?Sized> Pin<&'a mut T> {
/// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
- #[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
- pub fn into_ref(self) -> Pin<&'a T> {
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ #[stable(feature = "pin", since = "1.33.0")]
+ pub const fn into_ref(self) -> Pin<&'a T> {
Pin { pointer: self.pointer }
}
@@ -717,9 +723,10 @@
/// that lives for as long as the borrow of the `Pin`, not the lifetime of
/// the `Pin` itself. This method allows turning the `Pin` into a reference
/// with the same lifetime as the original `Pin`.
- #[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
- pub fn get_mut(self) -> &'a mut T
+ #[stable(feature = "pin", since = "1.33.0")]
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ pub const fn get_mut(self) -> &'a mut T
where
T: Unpin,
{
@@ -736,9 +743,10 @@
///
/// If the underlying data is `Unpin`, `Pin::get_mut` should be used
/// instead.
- #[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
- pub unsafe fn get_unchecked_mut(self) -> &'a mut T {
+ #[stable(feature = "pin", since = "1.33.0")]
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ pub const unsafe fn get_unchecked_mut(self) -> &'a mut T {
self.pointer
}
@@ -756,7 +764,7 @@
/// because it is one of the fields of that value), and also that you do
/// not move out of the argument you receive to the interior function.
///
- /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
+ /// [`pin` module]: self#projections-and-structural-pinning
#[stable(feature = "pin", since = "1.33.0")]
pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
where
@@ -773,6 +781,34 @@
}
}
+impl<T: ?Sized> Pin<&'static T> {
+ /// Get a pinned reference from a static reference.
+ ///
+ /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+ /// never ends.
+ #[unstable(feature = "pin_static_ref", issue = "none")]
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ pub const fn static_ref(r: &'static T) -> Pin<&'static T> {
+ // SAFETY: The 'static borrow guarantees the data will not be
+ // moved/invalidated until it gets dropped (which is never).
+ unsafe { Pin::new_unchecked(r) }
+ }
+}
+
+impl<T: ?Sized> Pin<&'static mut T> {
+ /// Get a pinned mutable reference from a static mutable reference.
+ ///
+ /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+ /// never ends.
+ #[unstable(feature = "pin_static_ref", issue = "none")]
+ #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+ pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> {
+ // SAFETY: The 'static borrow guarantees the data will not be
+ // moved/invalidated until it gets dropped (which is never).
+ unsafe { Pin::new_unchecked(r) }
+ }
+}
+
#[stable(feature = "pin", since = "1.33.0")]
impl<P: Deref> Deref for Pin<P> {
type Target = P::Target;
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index fc70dec..d09cdb4 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -836,7 +836,7 @@
/// # use std::mem::align_of;
/// # unsafe {
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = &x[n] as *const u8;
+ /// let ptr = x.as_ptr().add(n) as *const u8;
/// let offset = ptr.align_offset(align_of::<u16>());
/// if offset < x.len() - n - 1 {
/// let u16_ptr = ptr.add(offset) as *const u16;
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 68b5d1d..92c4f2c 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -54,16 +54,9 @@
//! [aliasing]: ../../nomicon/aliasing.html
//! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
//! [ub]: ../../reference/behavior-considered-undefined.html
-//! [null]: ./fn.null.html
//! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts
-//! [atomic operations]: ../../std/sync/atomic/index.html
-//! [`copy`]: ../../std/ptr/fn.copy.html
+//! [atomic operations]: crate::sync::atomic
//! [`offset`]: ../../std/primitive.pointer.html#method.offset
-//! [`read_unaligned`]: ./fn.read_unaligned.html
-//! [`write_unaligned`]: ./fn.write_unaligned.html
-//! [`read_volatile`]: ./fn.read_volatile.html
-//! [`write_volatile`]: ./fn.write_volatile.html
-//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
#![stable(feature = "rust1", since = "1.0.0")]
@@ -118,9 +111,9 @@
/// done automatically by the compiler. This means the fields of packed structs
/// are not dropped in-place.
///
-/// [`ptr::read`]: ../ptr/fn.read.html
-/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html
-/// [pinned]: ../pin/index.html
+/// [`ptr::read`]: self::read
+/// [`ptr::read_unaligned`]: self::read_unaligned
+/// [pinned]: crate::pin
///
/// # Safety
///
@@ -136,14 +129,12 @@
/// Additionally, if `T` is not [`Copy`], using the pointed-to value after
/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
/// foo` counts as a use because it will cause the value to be dropped
-/// again. [`write`] can be used to overwrite data without causing it to be
+/// again. [`write()`] can be used to overwrite data without causing it to be
/// dropped.
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
-/// [`Copy`]: ../marker/trait.Copy.html
-/// [`write`]: ../ptr/fn.write.html
+/// [valid]: self#safety
///
/// # Examples
///
@@ -243,9 +234,9 @@
/// The `len` argument is the number of **elements**, not the number of bytes.
///
/// This function is safe, but actually using the return value is unsafe.
-/// See the documentation of [`from_raw_parts`] for slice safety requirements.
+/// See the documentation of [`slice::from_raw_parts`] for slice safety requirements.
///
-/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+/// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
///
/// # Examples
///
@@ -274,10 +265,9 @@
/// See the documentation of [`slice_from_raw_parts`] for more details.
///
/// This function is safe, but actually using the return value is unsafe.
-/// See the documentation of [`from_raw_parts_mut`] for slice safety requirements.
+/// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements.
///
-/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
-/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
+/// [`slice::from_raw_parts_mut`]: crate::slice::from_raw_parts_mut
///
/// # Examples
///
@@ -316,8 +306,6 @@
/// overlapping region of memory from `x` will be used. This is demonstrated
/// in the second example below.
///
-/// [`mem::swap`]: ../mem/fn.swap.html
-///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
@@ -328,7 +316,7 @@
///
/// Note that even if `T` has size `0`, the pointers must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
+/// [valid]: self#safety
///
/// # Examples
///
@@ -406,7 +394,7 @@
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is `0`,
/// the pointers must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
+/// [valid]: self#safety
///
/// # Examples
///
@@ -533,8 +521,6 @@
/// operates on raw pointers instead of references. When references are
/// available, [`mem::replace`] should be preferred.
///
-/// [`mem::replace`]: ../mem/fn.replace.html
-///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
@@ -547,7 +533,7 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
+/// [valid]: self#safety
///
/// # Examples
///
@@ -653,7 +639,7 @@
/// `*src` can violate memory safety. Note that assigning to `*src` counts as a
/// use because it will attempt to drop the value at `*src`.
///
-/// [`write`] can be used to overwrite data without causing it to be dropped.
+/// [`write()`] can be used to overwrite data without causing it to be dropped.
///
/// ```
/// use std::ptr;
@@ -682,11 +668,7 @@
/// assert_eq!(s, "bar");
/// ```
///
-/// [`mem::swap`]: ../mem/fn.swap.html
-/// [valid]: ../ptr/index.html#safety
-/// [`Copy`]: ../marker/trait.Copy.html
-/// [`read_unaligned`]: ./fn.read_unaligned.html
-/// [`write`]: ./fn.write.html
+/// [valid]: self#safety
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn read<T>(src: *const T) -> T {
@@ -723,11 +705,8 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL.
///
-/// [`Copy`]: ../marker/trait.Copy.html
-/// [`read`]: ./fn.read.html
-/// [`write_unaligned`]: ./fn.write_unaligned.html
-/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
-/// [valid]: ../ptr/index.html#safety
+/// [read-ownership]: read#ownership-of-the-returned-value
+/// [valid]: self#safety
///
/// ## On `packed` structs
///
@@ -819,8 +798,6 @@
/// This is appropriate for initializing uninitialized memory, or overwriting
/// memory that has previously been [`read`] from.
///
-/// [`read`]: ./fn.read.html
-///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
@@ -832,8 +809,7 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
-/// [`write_unaligned`]: ./fn.write_unaligned.html
+/// [valid]: self#safety
///
/// # Examples
///
@@ -888,8 +864,6 @@
/// assert_eq!(foo, "bar");
/// assert_eq!(bar, "foo");
/// ```
-///
-/// [`mem::swap`]: ../mem/fn.swap.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn write<T>(dst: *mut T, src: T) {
@@ -904,7 +878,7 @@
/// Overwrites a memory location with the given value without reading or
/// dropping the old value.
///
-/// Unlike [`write`], the pointer may be unaligned.
+/// Unlike [`write()`], the pointer may be unaligned.
///
/// `write_unaligned` does not drop the contents of `dst`. This is safe, but it
/// could leak allocations or resources, so care should be taken not to overwrite
@@ -916,9 +890,6 @@
/// This is appropriate for initializing uninitialized memory, or overwriting
/// memory that has previously been read with [`read_unaligned`].
///
-/// [`write`]: ./fn.write.html
-/// [`read_unaligned`]: ./fn.read_unaligned.html
-///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
@@ -927,7 +898,7 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL.
///
-/// [valid]: ../ptr/index.html#safety
+/// [valid]: self#safety
///
/// ## On `packed` structs
///
@@ -1007,8 +978,6 @@
/// to not be elided or reordered by the compiler across other volatile
/// operations.
///
-/// [`write_volatile`]: ./fn.write_volatile.html
-///
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
@@ -1041,10 +1010,8 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
-/// [`Copy`]: ../marker/trait.Copy.html
-/// [`read`]: ./fn.read.html
-/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
+/// [valid]: self#safety
+/// [read-ownership]: read#ownership-of-the-returned-value
///
/// Just like in C, whether an operation is volatile has no bearing whatsoever
/// on questions involving concurrent access from multiple threads. Volatile
@@ -1089,8 +1056,6 @@
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
/// location pointed to by `dst`.
///
-/// [`read_volatile`]: ./fn.read_volatile.html
-///
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
@@ -1115,7 +1080,7 @@
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
///
-/// [valid]: ../ptr/index.html#safety
+/// [valid]: self#safety
///
/// Just like in C, whether an operation is volatile has no bearing whatsoever
/// on questions involving concurrent access from multiple threads. Volatile
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 2d25f21..537aa20 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1094,7 +1094,7 @@
/// # use std::mem::align_of;
/// # unsafe {
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = &x[n] as *const u8;
+ /// let ptr = x.as_ptr().add(n) as *const u8;
/// let offset = ptr.align_offset(align_of::<u16>());
/// if offset < x.len() - n - 1 {
/// let u16_ptr = ptr.add(offset) as *const u16;
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 294a317..5dc7171 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -34,8 +34,8 @@
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
/// is never used for mutation.
///
-/// [`PhantomData`]: ../marker/struct.PhantomData.html
-/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
+/// [`PhantomData`]: crate::marker::PhantomData
+/// [`UnsafeCell<T>`]: crate::cell::UnsafeCell
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
@@ -82,8 +82,8 @@
///
/// For the mutable counterpart see [`as_uninit_mut`].
///
- /// [`as_ref`]: #method.as_ref
- /// [`as_uninit_mut`]: #method.as_uninit_mut
+ /// [`as_ref`]: NonNull::as_ref
+ /// [`as_uninit_mut`]: NonNull::as_uninit_mut
///
/// # Safety
///
@@ -114,8 +114,8 @@
///
/// For the shared counterpart see [`as_uninit_ref`].
///
- /// [`as_mut`]: #method.as_mut
- /// [`as_uninit_ref`]: #method.as_uninit_ref
+ /// [`as_mut`]: NonNull::as_mut
+ /// [`as_uninit_ref`]: NonNull::as_uninit_ref
///
/// # Safety
///
@@ -181,8 +181,8 @@
///
/// For the mutable counterpart see [`as_mut`].
///
- /// [`as_uninit_ref`]: #method.as_uninit_ref
- /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_ref`]: NonNull::as_uninit_ref
+ /// [`as_mut`]: NonNull::as_mut
///
/// # Safety
///
@@ -217,8 +217,8 @@
///
/// For the shared counterpart see [`as_ref`].
///
- /// [`as_uninit_mut`]: #method.as_uninit_mut
- /// [`as_ref`]: #method.as_ref
+ /// [`as_uninit_mut`]: NonNull::as_uninit_mut
+ /// [`as_ref`]: NonNull::as_ref
///
/// # Safety
///
@@ -266,8 +266,6 @@
/// This function is safe, but dereferencing the return value is unsafe.
/// See the documentation of [`slice::from_raw_parts`] for slice safety requirements.
///
- /// [`slice::from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
- ///
/// # Examples
///
/// ```rust
@@ -357,8 +355,8 @@
///
/// For the mutable counterpart see [`as_uninit_slice_mut`].
///
- /// [`as_ref`]: #method.as_ref
- /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
+ /// [`as_ref`]: NonNull::as_ref
+ /// [`as_uninit_slice_mut`]: NonNull::as_uninit_slice_mut
///
/// # Safety
///
@@ -386,10 +384,9 @@
///
/// This applies even if the result of this method is unused!
///
- /// See also [`slice::from_raw_parts`][].
+ /// See also [`slice::from_raw_parts`].
///
/// [valid]: crate::ptr#safety
- /// [`NonNull::dangling()`]: NonNull::dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
#[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
@@ -403,8 +400,8 @@
///
/// For the shared counterpart see [`as_uninit_slice`].
///
- /// [`as_mut`]: #method.as_mut
- /// [`as_uninit_slice`]: #method.as_uninit_slice
+ /// [`as_mut`]: NonNull::as_mut
+ /// [`as_uninit_slice`]: NonNull::as_uninit_slice
///
/// # Safety
///
@@ -432,10 +429,9 @@
///
/// This applies even if the result of this method is unused!
///
- /// See also [`slice::from_raw_parts_mut`][].
+ /// See also [`slice::from_raw_parts_mut`].
///
/// [valid]: crate::ptr#safety
- /// [`NonNull::dangling()`]: NonNull::dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
///
/// # Examples
@@ -452,7 +448,7 @@
/// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized.
/// # #[allow(unused_variables)]
/// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() };
- /// # Ok::<_, std::alloc::AllocErr>(())
+ /// # Ok::<_, std::alloc::AllocError>(())
/// ```
#[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index 78647ee..cd6afdc 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -4,8 +4,6 @@
use crate::mem;
use crate::ops::{CoerceUnsized, DispatchFromDyn};
-// ignore-tidy-undocumented-unsafe
-
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
/// of this wrapper owns the referent. Useful for building abstractions like
/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index ade5472..5cec183 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -240,12 +240,12 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Result<T, E> {
/// Contains the success value
- #[cfg_attr(not(bootstrap), lang = "Ok")]
+ #[lang = "Ok"]
#[stable(feature = "rust1", since = "1.0.0")]
Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
/// Contains the error value
- #[cfg_attr(not(bootstrap), lang = "Err")]
+ #[lang = "Err"]
#[stable(feature = "rust1", since = "1.0.0")]
Err(#[stable(feature = "rust1", since = "1.0.0")] E),
}
@@ -273,7 +273,7 @@
/// assert_eq!(x.is_ok(), false);
/// ```
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
- #[rustc_const_unstable(feature = "const_result", issue = "67520")]
+ #[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_ok(&self) -> bool {
@@ -294,7 +294,7 @@
/// assert_eq!(x.is_err(), true);
/// ```
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
- #[rustc_const_unstable(feature = "const_result", issue = "67520")]
+ #[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn is_err(&self) -> bool {
@@ -438,7 +438,7 @@
/// assert_eq!(x.as_ref(), Err(&"Error"));
/// ```
#[inline]
- #[rustc_const_unstable(feature = "const_result", issue = "67520")]
+ #[rustc_const_stable(feature = "const_result", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn as_ref(&self) -> Result<&T, &E> {
match *self {
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
new file mode 100644
index 0000000..42032bc
--- /dev/null
+++ b/library/core/src/slice/ascii.rs
@@ -0,0 +1,156 @@
+//! Operations on ASCII `[u8]`.
+
+use crate::mem;
+
+#[lang = "slice_u8"]
+#[cfg(not(test))]
+impl [u8] {
+ /// Checks if all bytes in this slice are within the ASCII range.
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn is_ascii(&self) -> bool {
+ is_ascii(self)
+ }
+
+ /// Checks that two slices are an ASCII case-insensitive match.
+ ///
+ /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
+ /// but without allocating and copying temporaries.
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
+ self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.eq_ignore_ascii_case(b))
+ }
+
+ /// Converts this slice to its ASCII upper case equivalent in-place.
+ ///
+ /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new uppercased value without modifying the existing one, use
+ /// [`to_ascii_uppercase`].
+ ///
+ /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn make_ascii_uppercase(&mut self) {
+ for byte in self {
+ byte.make_ascii_uppercase();
+ }
+ }
+
+ /// Converts this slice to its ASCII lower case equivalent in-place.
+ ///
+ /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new lowercased value without modifying the existing one, use
+ /// [`to_ascii_lowercase`].
+ ///
+ /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn make_ascii_lowercase(&mut self) {
+ for byte in self {
+ byte.make_ascii_lowercase();
+ }
+ }
+}
+
+/// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed
+/// from `../str/mod.rs`, which does something similar for utf8 validation.
+#[inline]
+fn contains_nonascii(v: usize) -> bool {
+ const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
+ (NONASCII_MASK & v) != 0
+}
+
+/// Optimized ASCII test that will use usize-at-a-time operations instead of
+/// byte-at-a-time operations (when possible).
+///
+/// The algorithm we use here is pretty simple. If `s` is too short, we just
+/// check each byte and be done with it. Otherwise:
+///
+/// - Read the first word with an unaligned load.
+/// - Align the pointer, read subsequent words until end with aligned loads.
+/// - Read the last `usize` from `s` with an unaligned load.
+///
+/// If any of these loads produces something for which `contains_nonascii`
+/// (above) returns true, then we know the answer is false.
+#[inline]
+fn is_ascii(s: &[u8]) -> bool {
+ const USIZE_SIZE: usize = mem::size_of::<usize>();
+
+ let len = s.len();
+ let align_offset = s.as_ptr().align_offset(USIZE_SIZE);
+
+ // If we wouldn't gain anything from the word-at-a-time implementation, fall
+ // back to a scalar loop.
+ //
+ // We also do this for architectures where `size_of::<usize>()` isn't
+ // sufficient alignment for `usize`, because it's a weird edge case.
+ if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::<usize>() {
+ return s.iter().all(|b| b.is_ascii());
+ }
+
+ // We always read the first word unaligned, which means `align_offset` is
+ // 0, we'd read the same value again for the aligned read.
+ let offset_to_aligned = if align_offset == 0 { USIZE_SIZE } else { align_offset };
+
+ let start = s.as_ptr();
+ // SAFETY: We verify `len < USIZE_SIZE` above.
+ let first_word = unsafe { (start as *const usize).read_unaligned() };
+
+ if contains_nonascii(first_word) {
+ return false;
+ }
+ // We checked this above, somewhat implicitly. Note that `offset_to_aligned`
+ // is either `align_offset` or `USIZE_SIZE`, both of are explicitly checked
+ // above.
+ debug_assert!(offset_to_aligned <= len);
+
+ // SAFETY: word_ptr is the (properly aligned) usize ptr we use to read the
+ // middle chunk of the slice.
+ let mut word_ptr = unsafe { start.add(offset_to_aligned) as *const usize };
+
+ // `byte_pos` is the byte index of `word_ptr`, used for loop end checks.
+ let mut byte_pos = offset_to_aligned;
+
+ // Paranoia check about alignment, since we're about to do a bunch of
+ // unaligned loads. In practice this should be impossible barring a bug in
+ // `align_offset` though.
+ debug_assert_eq!((word_ptr as usize) % mem::align_of::<usize>(), 0);
+
+ // Read subsequent words until the last aligned word, excluding the last
+ // aligned word by itself to be done in tail check later, to ensure that
+ // tail is always one `usize` at most to extra branch `byte_pos == len`.
+ while byte_pos < len - USIZE_SIZE {
+ debug_assert!(
+ // Sanity check that the read is in bounds
+ (word_ptr as usize + USIZE_SIZE) <= (start.wrapping_add(len) as usize) &&
+ // And that our assumptions about `byte_pos` hold.
+ (word_ptr as usize) - (start as usize) == byte_pos
+ );
+
+ // SAFETY: We know `word_ptr` is properly aligned (because of
+ // `align_offset`), and we know that we have enough bytes between `word_ptr` and the end
+ let word = unsafe { word_ptr.read() };
+ if contains_nonascii(word) {
+ return false;
+ }
+
+ byte_pos += USIZE_SIZE;
+ // SAFETY: We know that `byte_pos <= len - USIZE_SIZE`, which means that
+ // after this `add`, `word_ptr` will be at most one-past-the-end.
+ word_ptr = unsafe { word_ptr.add(1) };
+ }
+
+ // Sanity check to ensure there really is only one `usize` left. This should
+ // be guaranteed by our loop condition.
+ debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE);
+
+ // SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start.
+ let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() };
+
+ !contains_nonascii(last_word)
+}
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
new file mode 100644
index 0000000..ed26c59
--- /dev/null
+++ b/library/core/src/slice/cmp.rs
@@ -0,0 +1,288 @@
+//! Comparison traits for `[T]`.
+
+use crate::cmp;
+use crate::cmp::Ordering::{self, Greater, Less};
+use crate::mem;
+
+use super::from_raw_parts;
+use super::memchr;
+
+extern "C" {
+ /// Calls implementation provided memcmp.
+ ///
+ /// Interprets the data as u8.
+ ///
+ /// Returns 0 for equal, < 0 for less than and > 0 for greater
+ /// than.
+ // FIXME(#32610): Return type should be c_int
+ fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B> PartialEq<[B]> for [A]
+where
+ A: PartialEq<B>,
+{
+ fn eq(&self, other: &[B]) -> bool {
+ SlicePartialEq::equal(self, other)
+ }
+
+ fn ne(&self, other: &[B]) -> bool {
+ SlicePartialEq::not_equal(self, other)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Eq> Eq for [T] {}
+
+/// Implements comparison of vectors lexicographically.
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Ord> Ord for [T] {
+ fn cmp(&self, other: &[T]) -> Ordering {
+ SliceOrd::compare(self, other)
+ }
+}
+
+/// Implements comparison of vectors lexicographically.
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: PartialOrd> PartialOrd for [T] {
+ fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
+ SlicePartialOrd::partial_compare(self, other)
+ }
+}
+
+#[doc(hidden)]
+// intermediate trait for specialization of slice's PartialEq
+trait SlicePartialEq<B> {
+ fn equal(&self, other: &[B]) -> bool;
+
+ fn not_equal(&self, other: &[B]) -> bool {
+ !self.equal(other)
+ }
+}
+
+// Generic slice equality
+impl<A, B> SlicePartialEq<B> for [A]
+where
+ A: PartialEq<B>,
+{
+ default fn equal(&self, other: &[B]) -> bool {
+ if self.len() != other.len() {
+ return false;
+ }
+
+ self.iter().zip(other.iter()).all(|(x, y)| x == y)
+ }
+}
+
+// Use an equal-pointer optimization when types are `Eq`
+// We can't make `A` and `B` the same type because `min_specialization` won't
+// allow it.
+impl<A, B> SlicePartialEq<B> for [A]
+where
+ A: MarkerEq<B>,
+{
+ default fn equal(&self, other: &[B]) -> bool {
+ if self.len() != other.len() {
+ return false;
+ }
+
+ // While performance would suffer if `guaranteed_eq` just returned `false`
+ // for all arguments, correctness and return value of this function are not affected.
+ if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) {
+ return true;
+ }
+
+ self.iter().zip(other.iter()).all(|(x, y)| x == y)
+ }
+}
+
+// Use memcmp for bytewise equality when the types allow
+impl<A, B> SlicePartialEq<B> for [A]
+where
+ A: BytewiseEquality<B>,
+{
+ fn equal(&self, other: &[B]) -> bool {
+ if self.len() != other.len() {
+ return false;
+ }
+
+ // While performance would suffer if `guaranteed_eq` just returned `false`
+ // for all arguments, correctness and return value of this function are not affected.
+ if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) {
+ return true;
+ }
+ // SAFETY: `self` and `other` are references and are thus guaranteed to be valid.
+ // The two slices have been checked to have the same size above.
+ unsafe {
+ let size = mem::size_of_val(self);
+ memcmp(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0
+ }
+ }
+}
+
+#[doc(hidden)]
+// intermediate trait for specialization of slice's PartialOrd
+trait SlicePartialOrd: Sized {
+ fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>;
+}
+
+impl<A: PartialOrd> SlicePartialOrd for A {
+ default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
+ let l = cmp::min(left.len(), right.len());
+
+ // Slice to the loop iteration range to enable bound check
+ // elimination in the compiler
+ let lhs = &left[..l];
+ let rhs = &right[..l];
+
+ for i in 0..l {
+ match lhs[i].partial_cmp(&rhs[i]) {
+ Some(Ordering::Equal) => (),
+ non_eq => return non_eq,
+ }
+ }
+
+ left.len().partial_cmp(&right.len())
+ }
+}
+
+// This is the impl that we would like to have. Unfortunately it's not sound.
+// See `partial_ord_slice.rs`.
+/*
+impl<A> SlicePartialOrd for A
+where
+ A: Ord,
+{
+ default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
+ Some(SliceOrd::compare(left, right))
+ }
+}
+*/
+
+impl<A: AlwaysApplicableOrd> SlicePartialOrd for A {
+ fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
+ Some(SliceOrd::compare(left, right))
+ }
+}
+
+#[rustc_specialization_trait]
+trait AlwaysApplicableOrd: SliceOrd + Ord {}
+
+macro_rules! always_applicable_ord {
+ ($([$($p:tt)*] $t:ty,)*) => {
+ $(impl<$($p)*> AlwaysApplicableOrd for $t {})*
+ }
+}
+
+always_applicable_ord! {
+ [] u8, [] u16, [] u32, [] u64, [] u128, [] usize,
+ [] i8, [] i16, [] i32, [] i64, [] i128, [] isize,
+ [] bool, [] char,
+ [T: ?Sized] *const T, [T: ?Sized] *mut T,
+ [T: AlwaysApplicableOrd] &T,
+ [T: AlwaysApplicableOrd] &mut T,
+ [T: AlwaysApplicableOrd] Option<T>,
+}
+
+#[doc(hidden)]
+// intermediate trait for specialization of slice's Ord
+trait SliceOrd: Sized {
+ fn compare(left: &[Self], right: &[Self]) -> Ordering;
+}
+
+impl<A: Ord> SliceOrd for A {
+ default fn compare(left: &[Self], right: &[Self]) -> Ordering {
+ let l = cmp::min(left.len(), right.len());
+
+ // Slice to the loop iteration range to enable bound check
+ // elimination in the compiler
+ let lhs = &left[..l];
+ let rhs = &right[..l];
+
+ for i in 0..l {
+ match lhs[i].cmp(&rhs[i]) {
+ Ordering::Equal => (),
+ non_eq => return non_eq,
+ }
+ }
+
+ left.len().cmp(&right.len())
+ }
+}
+
+// memcmp compares a sequence of unsigned bytes lexicographically.
+// this matches the order we want for [u8], but no others (not even [i8]).
+impl SliceOrd for u8 {
+ #[inline]
+ fn compare(left: &[Self], right: &[Self]) -> Ordering {
+ let order =
+ // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
+ // We use the minimum of both lengths which guarantees that both regions are
+ // valid for reads in that interval.
+ unsafe { memcmp(left.as_ptr(), right.as_ptr(), cmp::min(left.len(), right.len())) };
+ if order == 0 {
+ left.len().cmp(&right.len())
+ } else if order < 0 {
+ Less
+ } else {
+ Greater
+ }
+ }
+}
+
+// Hack to allow specializing on `Eq` even though `Eq` has a method.
+#[rustc_unsafe_specialization_marker]
+trait MarkerEq<T>: PartialEq<T> {}
+
+impl<T: Eq> MarkerEq<T> for T {}
+
+#[doc(hidden)]
+/// Trait implemented for types that can be compared for equality using
+/// their bytewise representation
+#[rustc_specialization_trait]
+trait BytewiseEquality<T>: MarkerEq<T> + Copy {}
+
+macro_rules! impl_marker_for {
+ ($traitname:ident, $($ty:ty)*) => {
+ $(
+ impl $traitname<$ty> for $ty { }
+ )*
+ }
+}
+
+impl_marker_for!(BytewiseEquality,
+ u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize char bool);
+
+pub(super) trait SliceContains: Sized {
+ fn slice_contains(&self, x: &[Self]) -> bool;
+}
+
+impl<T> SliceContains for T
+where
+ T: PartialEq,
+{
+ default fn slice_contains(&self, x: &[Self]) -> bool {
+ x.iter().any(|y| *y == *self)
+ }
+}
+
+impl SliceContains for u8 {
+ #[inline]
+ fn slice_contains(&self, x: &[Self]) -> bool {
+ memchr::memchr(*self, x).is_some()
+ }
+}
+
+impl SliceContains for i8 {
+ #[inline]
+ fn slice_contains(&self, x: &[Self]) -> bool {
+ let byte = *self as u8;
+ // SAFETY: `i8` and `u8` have the same memory layout, thus casting `x.as_ptr()`
+ // as `*const u8` is safe. The `x.as_ptr()` comes from a reference and is thus guaranteed
+ // to be valid for reads for the length of the slice `x.len()`, which cannot be larger
+ // than `isize::MAX`. The returned slice is never mutated.
+ let bytes: &[u8] = unsafe { from_raw_parts(x.as_ptr() as *const u8, x.len()) };
+ memchr::memchr(byte, bytes).is_some()
+ }
+}
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
new file mode 100644
index 0000000..16fcb62
--- /dev/null
+++ b/library/core/src/slice/index.rs
@@ -0,0 +1,528 @@
+//! Indexing implementations for `[T]`.
+
+use crate::ops::{self, Bound, Range, RangeBounds};
+use crate::ptr;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, I> ops::Index<I> for [T]
+where
+ I: SliceIndex<[T]>,
+{
+ type Output = I::Output;
+
+ #[inline]
+ fn index(&self, index: I) -> &I::Output {
+ index.index(self)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, I> ops::IndexMut<I> for [T]
+where
+ I: SliceIndex<[T]>,
+{
+ #[inline]
+ fn index_mut(&mut self, index: I) -> &mut I::Output {
+ index.index_mut(self)
+ }
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
+ panic!("range start index {} out of range for slice of length {}", index, len);
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+pub(super) fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
+ panic!("range end index {} out of range for slice of length {}", index, len);
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+pub(super) fn slice_index_order_fail(index: usize, end: usize) -> ! {
+ panic!("slice index starts at {} but ends at {}", index, end);
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+pub(super) fn slice_start_index_overflow_fail() -> ! {
+ panic!("attempted to index slice from after maximum usize");
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+pub(super) fn slice_end_index_overflow_fail() -> ! {
+ panic!("attempted to index slice up to maximum usize");
+}
+
+/// Performs bounds-checking of the given range.
+/// The returned [`Range`] is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]
+/// for slices of the given length.
+///
+/// [`get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
+/// [`get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
+///
+/// # Panics
+///
+/// Panics if the range is out of bounds.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(slice_check_range)]
+/// use std::slice;
+///
+/// let v = [10, 40, 30];
+/// assert_eq!(1..2, slice::check_range(v.len(), 1..2));
+/// assert_eq!(0..2, slice::check_range(v.len(), ..2));
+/// assert_eq!(1..3, slice::check_range(v.len(), 1..));
+/// ```
+///
+/// Panics when [`Index::index`] would panic:
+///
+/// ```should_panic
+/// #![feature(slice_check_range)]
+///
+/// std::slice::check_range(3, 2..1);
+/// ```
+///
+/// ```should_panic
+/// #![feature(slice_check_range)]
+///
+/// std::slice::check_range(3, 1..4);
+/// ```
+///
+/// ```should_panic
+/// #![feature(slice_check_range)]
+///
+/// std::slice::check_range(3, 1..=usize::MAX);
+/// ```
+///
+/// [`Index::index`]: ops::Index::index
+#[track_caller]
+#[unstable(feature = "slice_check_range", issue = "76393")]
+pub fn check_range<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> {
+ let start = match range.start_bound() {
+ Bound::Included(&start) => start,
+ Bound::Excluded(start) => {
+ start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
+ }
+ Bound::Unbounded => 0,
+ };
+
+ let end = match range.end_bound() {
+ Bound::Included(end) => {
+ end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
+ }
+ Bound::Excluded(&end) => end,
+ Bound::Unbounded => len,
+ };
+
+ if start > end {
+ slice_index_order_fail(start, end);
+ }
+ if end > len {
+ slice_end_index_len_fail(end, len);
+ }
+
+ Range { start, end }
+}
+
+mod private_slice_index {
+ use super::ops;
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ pub trait Sealed {}
+
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for usize {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::Range<usize> {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::RangeTo<usize> {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::RangeFrom<usize> {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::RangeFull {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::RangeInclusive<usize> {}
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ impl Sealed for ops::RangeToInclusive<usize> {}
+}
+
+/// A helper trait used for indexing operations.
+///
+/// Implementations of this trait have to promise that if the argument
+/// to `get_(mut_)unchecked` is a safe reference, then so is the result.
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
+#[rustc_on_unimplemented(
+ on(T = "str", label = "string indices are ranges of `usize`",),
+ on(
+ all(any(T = "str", T = "&str", T = "std::string::String"), _Self = "{integer}"),
+ note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
+ for more information, see chapter 8 in The Book: \
+ <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
+ ),
+ message = "the type `{T}` cannot be indexed by `{Self}`",
+ label = "slice indices are of type `usize` or ranges of `usize`"
+)]
+pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
+ /// The output type returned by methods.
+ #[stable(feature = "slice_get_slice", since = "1.28.0")]
+ type Output: ?Sized;
+
+ /// Returns a shared reference to the output at this location, if in
+ /// bounds.
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ fn get(self, slice: &T) -> Option<&Self::Output>;
+
+ /// Returns a mutable reference to the output at this location, if in
+ /// bounds.
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
+
+ /// Returns a shared reference to the output at this location, without
+ /// performing any bounds checking.
+ /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
+ /// is *[undefined behavior]* even if the resulting reference is not used.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+ /// Returns a mutable reference to the output at this location, without
+ /// performing any bounds checking.
+ /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
+ /// is *[undefined behavior]* even if the resulting reference is not used.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
+
+ /// Returns a shared reference to the output at this location, panicking
+ /// if out of bounds.
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ #[track_caller]
+ fn index(self, slice: &T) -> &Self::Output;
+
+ /// Returns a mutable reference to the output at this location, panicking
+ /// if out of bounds.
+ #[unstable(feature = "slice_index_methods", issue = "none")]
+ #[track_caller]
+ fn index_mut(self, slice: &mut T) -> &mut Self::Output;
+}
+
+#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
+unsafe impl<T> SliceIndex<[T]> for usize {
+ type Output = T;
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&T> {
+ // SAFETY: `self` is checked to be in bounds.
+ if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None }
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
+ // SAFETY: `self` is checked to be in bounds.
+ if self < slice.len() { unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } else { None }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+ // SAFETY: the caller guarantees that `slice` is not dangling, so it
+ // cannot be longer than `isize::MAX`. They also guarantee that
+ // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+ // so the call to `add` is safe.
+ unsafe { slice.as_ptr().add(self) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
+ // SAFETY: see comments for `get_unchecked` above.
+ unsafe { slice.as_mut_ptr().add(self) }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &T {
+ // N.B., use intrinsic indexing
+ &(*slice)[self]
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut T {
+ // N.B., use intrinsic indexing
+ &mut (*slice)[self]
+ }
+}
+
+#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ if self.start > self.end || self.end > slice.len() {
+ None
+ } else {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { Some(&*self.get_unchecked(slice)) }
+ }
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ if self.start > self.end || self.end > slice.len() {
+ None
+ } else {
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { Some(&mut *self.get_unchecked_mut(slice)) }
+ }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ // SAFETY: the caller guarantees that `slice` is not dangling, so it
+ // cannot be longer than `isize::MAX`. They also guarantee that
+ // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+ // so the call to `add` is safe.
+ unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ // SAFETY: see comments for `get_unchecked` above.
+ unsafe {
+ ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
+ }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ if self.start > self.end {
+ slice_index_order_fail(self.start, self.end);
+ } else if self.end > slice.len() {
+ slice_end_index_len_fail(self.end, slice.len());
+ }
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &*self.get_unchecked(slice) }
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ if self.start > self.end {
+ slice_index_order_fail(self.start, self.end);
+ } else if self.end > slice.len() {
+ slice_end_index_len_fail(self.end, slice.len());
+ }
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &mut *self.get_unchecked_mut(slice) }
+ }
+}
+
+#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ (0..self.end).get(slice)
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ (0..self.end).get_mut(slice)
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+ unsafe { (0..self.end).get_unchecked(slice) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (0..self.end).get_unchecked_mut(slice) }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ (0..self.end).index(slice)
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ (0..self.end).index_mut(slice)
+ }
+}
+
+#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ (self.start..slice.len()).get(slice)
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ (self.start..slice.len()).get_mut(slice)
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+ unsafe { (self.start..slice.len()).get_unchecked(slice) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ if self.start > slice.len() {
+ slice_start_index_len_fail(self.start, slice.len());
+ }
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &*self.get_unchecked(slice) }
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ if self.start > slice.len() {
+ slice_start_index_len_fail(self.start, slice.len());
+ }
+ // SAFETY: `self` is checked to be valid and in bounds above.
+ unsafe { &mut *self.get_unchecked_mut(slice) }
+ }
+}
+
+#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ Some(slice)
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ Some(slice)
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ slice
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ slice
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ slice
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ slice
+ }
+}
+
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ if *self.end() == usize::MAX {
+ None
+ } else {
+ (*self.start()..self.end() + 1).get_mut(slice)
+ }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+ unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ if *self.end() == usize::MAX {
+ slice_end_index_overflow_fail();
+ }
+ (*self.start()..self.end() + 1).index(slice)
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ if *self.end() == usize::MAX {
+ slice_end_index_overflow_fail();
+ }
+ (*self.start()..self.end() + 1).index_mut(slice)
+ }
+}
+
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
+ type Output = [T];
+
+ #[inline]
+ fn get(self, slice: &[T]) -> Option<&[T]> {
+ (0..=self.end).get(slice)
+ }
+
+ #[inline]
+ fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+ (0..=self.end).get_mut(slice)
+ }
+
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+ unsafe { (0..=self.end).get_unchecked(slice) }
+ }
+
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (0..=self.end).get_unchecked_mut(slice) }
+ }
+
+ #[inline]
+ fn index(self, slice: &[T]) -> &[T] {
+ (0..=self.end).index(slice)
+ }
+
+ #[inline]
+ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+ (0..=self.end).index_mut(slice)
+ }
+}
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
new file mode 100644
index 0000000..793cbf9
--- /dev/null
+++ b/library/core/src/slice/iter.rs
@@ -0,0 +1,2979 @@
+//! Definitions of a bunch of iterators for `[T]`.
+
+#[macro_use] // import iterator! and forward_iterator!
+mod macros;
+
+use crate::cmp;
+use crate::cmp::Ordering;
+use crate::fmt;
+use crate::intrinsics::{assume, exact_div, unchecked_sub};
+use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
+use crate::marker::{PhantomData, Send, Sized, Sync};
+use crate::mem;
+use crate::ptr::NonNull;
+
+use super::{from_raw_parts, from_raw_parts_mut};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> IntoIterator for &'a [T] {
+ type Item = &'a T;
+ type IntoIter = Iter<'a, T>;
+
+ fn into_iter(self) -> Iter<'a, T> {
+ self.iter()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> IntoIterator for &'a mut [T] {
+ type Item = &'a mut T;
+ type IntoIter = IterMut<'a, T>;
+
+ fn into_iter(self) -> IterMut<'a, T> {
+ self.iter_mut()
+ }
+}
+
+// Macro helper functions
+#[inline(always)]
+fn size_from_ptr<T>(_: *const T) -> usize {
+ mem::size_of::<T>()
+}
+
+/// Immutable slice iterator
+///
+/// This struct is created by the [`iter`] method on [slices].
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]):
+/// let slice = &[1, 2, 3];
+///
+/// // Then, we iterate over it:
+/// for element in slice.iter() {
+/// println!("{}", element);
+/// }
+/// ```
+///
+/// [`iter`]: ../../std/primitive.slice.html#method.iter
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Iter<'a, T: 'a> {
+ ptr: NonNull<T>,
+ end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
+ // ptr == end is a quick test for the Iterator being empty, that works
+ // for both ZST and non-ZST.
+ _marker: PhantomData<&'a T>,
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("Iter").field(&self.as_slice()).finish()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<T: Sync> Sync for Iter<'_, T> {}
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<T: Sync> Send for Iter<'_, T> {}
+
+impl<'a, T> Iter<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T]) -> Self {
+ let ptr = slice.as_ptr();
+ // SAFETY: Similar to `IterMut::new`.
+ unsafe {
+ assume(!ptr.is_null());
+
+ let end = if mem::size_of::<T>() == 0 {
+ (ptr as *const u8).wrapping_add(slice.len()) as *const T
+ } else {
+ ptr.add(slice.len())
+ };
+
+ Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData }
+ }
+ }
+
+ /// Views the underlying data as a subslice of the original data.
+ ///
+ /// This has the same lifetime as the original slice, and so the
+ /// iterator can continue to be used while this exists.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// // First, we declare a type which has the `iter` method to get the `Iter`
+ /// // struct (&[usize here]):
+ /// let slice = &[1, 2, 3];
+ ///
+ /// // Then, we get the iterator:
+ /// let mut iter = slice.iter();
+ /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]":
+ /// println!("{:?}", iter.as_slice());
+ ///
+ /// // Next, we move to the second element of the slice:
+ /// iter.next();
+ /// // Now `as_slice` returns "[2, 3]":
+ /// println!("{:?}", iter.as_slice());
+ /// ```
+ #[stable(feature = "iter_to_slice", since = "1.4.0")]
+ pub fn as_slice(&self) -> &'a [T] {
+ self.make_slice()
+ }
+}
+
+iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, {
+ fn is_sorted_by<F>(self, mut compare: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
+ {
+ self.as_slice().windows(2).all(|w| {
+ compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false)
+ })
+ }
+}}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Clone for Iter<'_, T> {
+ fn clone(&self) -> Self {
+ Iter { ptr: self.ptr, end: self.end, _marker: self._marker }
+ }
+}
+
+#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
+impl<T> AsRef<[T]> for Iter<'_, T> {
+ fn as_ref(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+/// Mutable slice iterator.
+///
+/// This struct is created by the [`iter_mut`] method on [slices].
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
+/// // struct (&[usize here]):
+/// let mut slice = &mut [1, 2, 3];
+///
+/// // Then, we iterate over it and increment each element value:
+/// for element in slice.iter_mut() {
+/// *element += 1;
+/// }
+///
+/// // We now have "[2, 3, 4]":
+/// println!("{:?}", slice);
+/// ```
+///
+/// [`iter_mut`]: ../../std/primitive.slice.html#method.iter_mut
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IterMut<'a, T: 'a> {
+ ptr: NonNull<T>,
+ end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
+ // ptr == end is a quick test for the Iterator being empty, that works
+ // for both ZST and non-ZST.
+ _marker: PhantomData<&'a mut T>,
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("IterMut").field(&self.make_slice()).finish()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<T: Send> Send for IterMut<'_, T> {}
+
+impl<'a, T> IterMut<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T]) -> Self {
+ let ptr = slice.as_mut_ptr();
+ // SAFETY: There are several things here:
+ //
+ // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
+ // reference thus it is non-NUL and safe to use and pass to
+ // `NonNull::new_unchecked` .
+ //
+ // Adding `slice.len()` to the starting pointer gives a pointer
+ // at the end of `slice`. `end` will never be dereferenced, only checked
+ // for direct pointer equality with `ptr` to check if the iterator is
+ // done.
+ //
+ // In the case of a ZST, the end pointer is just the start pointer plus
+ // the length, to also allows for the fast `ptr == end` check.
+ //
+ // See the `next_unchecked!` and `is_empty!` macros as well as the
+ // `post_inc_start` method for more informations.
+ unsafe {
+ assume(!ptr.is_null());
+
+ let end = if mem::size_of::<T>() == 0 {
+ (ptr as *mut u8).wrapping_add(slice.len()) as *mut T
+ } else {
+ ptr.add(slice.len())
+ };
+
+ Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData }
+ }
+ }
+
+ /// Views the underlying data as a subslice of the original data.
+ ///
+ /// To avoid creating `&mut` references that alias, this is forced
+ /// to consume the iterator.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// // First, we declare a type which has `iter_mut` method to get the `IterMut`
+ /// // struct (&[usize here]):
+ /// let mut slice = &mut [1, 2, 3];
+ ///
+ /// {
+ /// // Then, we get the iterator:
+ /// let mut iter = slice.iter_mut();
+ /// // We move to next element:
+ /// iter.next();
+ /// // So if we print what `into_slice` method returns here, we have "[2, 3]":
+ /// println!("{:?}", iter.into_slice());
+ /// }
+ ///
+ /// // Now let's modify a value of the slice:
+ /// {
+ /// // First we get back the iterator:
+ /// let mut iter = slice.iter_mut();
+ /// // We change the value of the first element of the slice returned by the `next` method:
+ /// *iter.next().unwrap() += 1;
+ /// }
+ /// // Now slice is "[2, 2, 3]":
+ /// println!("{:?}", slice);
+ /// ```
+ #[stable(feature = "iter_to_slice", since = "1.4.0")]
+ pub fn into_slice(self) -> &'a mut [T] {
+ // SAFETY: the iterator was created from a mutable slice with pointer
+ // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
+ // for `from_raw_parts_mut` are fulfilled.
+ unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
+ }
+
+ /// Views the underlying data as a subslice of the original data.
+ ///
+ /// To avoid creating `&mut [T]` references that alias, the returned slice
+ /// borrows its lifetime from the iterator the method is applied on.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// # #![feature(slice_iter_mut_as_slice)]
+ /// let mut slice: &mut [usize] = &mut [1, 2, 3];
+ ///
+ /// // First, we get the iterator:
+ /// let mut iter = slice.iter_mut();
+ /// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]":
+ /// assert_eq!(iter.as_slice(), &[1, 2, 3]);
+ ///
+ /// // Next, we move to the second element of the slice:
+ /// iter.next();
+ /// // Now `as_slice` returns "[2, 3]":
+ /// assert_eq!(iter.as_slice(), &[2, 3]);
+ /// ```
+ #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")]
+ pub fn as_slice(&self) -> &[T] {
+ self.make_slice()
+ }
+}
+
+iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
+
+/// An internal abstraction over the splitting iterators, so that
+/// splitn, splitn_mut etc can be implemented once.
+#[doc(hidden)]
+pub(super) trait SplitIter: DoubleEndedIterator {
+ /// Marks the underlying iterator as complete, extracting the remaining
+ /// portion of the slice.
+ fn finish(&mut self) -> Option<Self::Item>;
+}
+
+/// An iterator over subslices separated by elements that match a predicate
+/// function.
+///
+/// This struct is created by the [`split`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 33, 20];
+/// let mut iter = slice.split(|num| num % 3 == 0);
+/// ```
+///
+/// [`split`]: ../../std/primitive.slice.html#method.split
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Split<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a [T],
+ pred: P,
+ finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+ Self { v: slice, pred, finished: false }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish()
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, P> Clone for Split<'_, T, P>
+where
+ P: Clone + FnMut(&T) -> bool,
+{
+ fn clone(&self) -> Self {
+ Split { v: self.v, pred: self.pred.clone(), finished: self.finished }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, P> Iterator for Split<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ match self.v.iter().position(|x| (self.pred)(x)) {
+ None => self.finish(),
+ Some(idx) => {
+ let ret = Some(&self.v[..idx]);
+ self.v = &self.v[idx + 1..];
+ ret
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ match self.v.iter().rposition(|x| (self.pred)(x)) {
+ None => self.finish(),
+ Some(idx) => {
+ let ret = Some(&self.v[idx + 1..]);
+ self.v = &self.v[..idx];
+ ret
+ }
+ }
+ }
+}
+
+impl<'a, T, P> SplitIter for Split<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn finish(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ None
+ } else {
+ self.finished = true;
+ Some(self.v)
+ }
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over subslices separated by elements that match a predicate
+/// function. Unlike `Split`, it contains the matched part as a terminator
+/// of the subslice.
+///
+/// This struct is created by the [`split_inclusive`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// #![feature(split_inclusive)]
+///
+/// let slice = [10, 40, 33, 20];
+/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+/// ```
+///
+/// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "split_inclusive", issue = "72360")]
+pub struct SplitInclusive<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a [T],
+ pred: P,
+ finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+ Self { v: slice, pred, finished: false }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusive")
+ .field("v", &self.v)
+ .field("finished", &self.finished)
+ .finish()
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<T, P> Clone for SplitInclusive<'_, T, P>
+where
+ P: Clone + FnMut(&T) -> bool,
+{
+ fn clone(&self) -> Self {
+ SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx =
+ self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
+ if idx == self.v.len() {
+ self.finished = true;
+ }
+ let ret = Some(&self.v[..idx]);
+ self.v = &self.v[idx..];
+ ret
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.finished {
+ return None;
+ }
+
+ // The last index of self.v is already checked and found to match
+ // by the last iteration, so we start searching a new match
+ // one index to the left.
+ let remainder = if self.v.is_empty() { &[] } else { &self.v[..(self.v.len() - 1)] };
+ let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
+ if idx == 0 {
+ self.finished = true;
+ }
+ let ret = Some(&self.v[idx..]);
+ self.v = &self.v[..idx];
+ ret
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the mutable subslices of the vector which are separated
+/// by elements that match `pred`.
+///
+/// This struct is created by the [`split_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut v = [10, 40, 30, 20, 60, 50];
+/// let iter = v.split_mut(|num| *num % 3 == 0);
+/// ```
+///
+/// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SplitMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a mut [T],
+ pred: P,
+ finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+ Self { v: slice, pred, finished: false }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish()
+ }
+}
+
+impl<'a, T, P> SplitIter for SplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn finish(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ None
+ } else {
+ self.finished = true;
+ Some(mem::replace(&mut self.v, &mut []))
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, P> Iterator for SplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+ self.v.iter().position(|x| (*pred)(x))
+ };
+ match idx_opt {
+ None => self.finish(),
+ Some(idx) => {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = &mut tail[1..];
+ Some(head)
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished {
+ (0, Some(0))
+ } else {
+ // if the predicate doesn't match anything, we yield one slice
+ // if it matches every element, we yield len+1 empty slices.
+ (1, Some(self.v.len() + 1))
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+ self.v.iter().rposition(|x| (*pred)(x))
+ };
+ match idx_opt {
+ None => self.finish(),
+ Some(idx) => {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = head;
+ Some(&mut tail[1..])
+ }
+ }
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the mutable subslices of the vector which are separated
+/// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
+/// parts in the ends of the subslices.
+///
+/// This struct is created by the [`split_inclusive_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// #![feature(split_inclusive)]
+///
+/// let mut v = [10, 40, 30, 20, 60, 50];
+/// let iter = v.split_inclusive_mut(|num| *num % 3 == 0);
+/// ```
+///
+/// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "split_inclusive", issue = "72360")]
+pub struct SplitInclusiveMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ v: &'a mut [T],
+ pred: P,
+ finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+ Self { v: slice, pred, finished: false }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusiveMut")
+ .field("v", &self.v)
+ .field("finished", &self.finished)
+ .finish()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+ self.v.iter().position(|x| (*pred)(x))
+ };
+ let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
+ if idx == self.v.len() {
+ self.finished = true;
+ }
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = tail;
+ Some(head)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.finished {
+ (0, Some(0))
+ } else {
+ // if the predicate doesn't match anything, we yield one slice
+ // if it matches every element, we yield len+1 empty slices.
+ (1, Some(self.v.len() + 1))
+ }
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.finished {
+ return None;
+ }
+
+ let idx_opt = if self.v.is_empty() {
+ None
+ } else {
+ // work around borrowck limitations
+ let pred = &mut self.pred;
+
+ // The last index of self.v is already checked and found to match
+ // by the last iteration, so we start searching a new match
+ // one index to the left.
+ let remainder = &self.v[..(self.v.len() - 1)];
+ remainder.iter().rposition(|x| (*pred)(x))
+ };
+ let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
+ if idx == 0 {
+ self.finished = true;
+ }
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(idx);
+ self.v = head;
+ Some(tail)
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over subslices separated by elements that match a predicate
+/// function, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = [11, 22, 33, 0, 44, 55];
+/// let iter = slice.rsplit(|num| *num == 0);
+/// ```
+///
+/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
+pub struct RSplit<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: Split<'a, T, P>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+ Self { inner: Split::new(slice, pred) }
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RSplit")
+ .field("v", &self.inner.v)
+ .field("finished", &self.inner.finished)
+ .finish()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> Iterator for RSplit<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ self.inner.next_back()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ self.inner.next()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> SplitIter for RSplit<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn finish(&mut self) -> Option<&'a [T]> {
+ self.inner.finish()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the subslices of the vector which are separated
+/// by elements that match `pred`, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = [11, 22, 33, 0, 44, 55];
+/// let iter = slice.rsplit_mut(|num| *num == 0);
+/// ```
+///
+/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+pub struct RSplitMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: SplitMut<'a, T, P>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+ Self { inner: SplitMut::new(slice, pred) }
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RSplitMut")
+ .field("v", &self.inner.v)
+ .field("finished", &self.inner.finished)
+ .finish()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> SplitIter for RSplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn finish(&mut self) -> Option<&'a mut [T]> {
+ self.inner.finish()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> Iterator for RSplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ self.inner.next_back()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ self.inner.next()
+ }
+}
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
+
+/// An private iterator over subslices separated by elements that
+/// match a predicate function, splitting at most a fixed number of
+/// times.
+#[derive(Debug)]
+struct GenericSplitN<I> {
+ iter: I,
+ count: usize,
+}
+
+impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
+ type Item = T;
+
+ #[inline]
+ fn next(&mut self) -> Option<T> {
+ match self.count {
+ 0 => None,
+ 1 => {
+ self.count -= 1;
+ self.iter.finish()
+ }
+ _ => {
+ self.count -= 1;
+ self.iter.next()
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (lower, upper_opt) = self.iter.size_hint();
+ (lower, upper_opt.map(|upper| cmp::min(self.count, upper)))
+ }
+}
+
+/// An iterator over subslices separated by elements that match a predicate
+/// function, limited to a given number of splits.
+///
+/// This struct is created by the [`splitn`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.splitn(2, |num| *num % 3 == 0);
+/// ```
+///
+/// [`splitn`]: ../../std/primitive.slice.html#method.splitn
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SplitN<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: GenericSplitN<Split<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
+ #[inline]
+ pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
+ Self { inner: GenericSplitN { iter: s, count: n } }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitN").field("inner", &self.inner).finish()
+ }
+}
+
+/// An iterator over subslices separated by elements that match a
+/// predicate function, limited to a given number of splits, starting
+/// from the end of the slice.
+///
+/// This struct is created by the [`rsplitn`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.rsplitn(2, |num| *num % 3 == 0);
+/// ```
+///
+/// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RSplitN<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: GenericSplitN<RSplit<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
+ #[inline]
+ pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
+ Self { inner: GenericSplitN { iter: s, count: n } }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RSplitN").field("inner", &self.inner).finish()
+ }
+}
+
+/// An iterator over subslices separated by elements that match a predicate
+/// function, limited to a given number of splits.
+///
+/// This struct is created by the [`splitn_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.splitn_mut(2, |num| *num % 3 == 0);
+/// ```
+///
+/// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SplitNMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: GenericSplitN<SplitMut<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
+ #[inline]
+ pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
+ Self { inner: GenericSplitN { iter: s, count: n } }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitNMut").field("inner", &self.inner).finish()
+ }
+}
+
+/// An iterator over subslices separated by elements that match a
+/// predicate function, limited to a given number of splits, starting
+/// from the end of the slice.
+///
+/// This struct is created by the [`rsplitn_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = [10, 40, 30, 20, 60, 50];
+/// let iter = slice.rsplitn_mut(2, |num| *num % 3 == 0);
+/// ```
+///
+/// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut
+/// [slices]: ../../std/primitive.slice.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RSplitNMut<'a, T: 'a, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ inner: GenericSplitN<RSplitMut<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
+ #[inline]
+ pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
+ Self { inner: GenericSplitN { iter: s, count: n } }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P>
+where
+ P: FnMut(&T) -> bool,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RSplitNMut").field("inner", &self.inner).finish()
+ }
+}
+
+forward_iterator! { SplitN: T, &'a [T] }
+forward_iterator! { RSplitN: T, &'a [T] }
+forward_iterator! { SplitNMut: T, &'a mut [T] }
+forward_iterator! { RSplitNMut: T, &'a mut [T] }
+
+/// An iterator over overlapping subslices of length `size`.
+///
+/// This struct is created by the [`windows`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = ['r', 'u', 's', 't'];
+/// let iter = slice.windows(2);
+/// ```
+///
+/// [`windows`]: ../../std/primitive.slice.html#method.windows
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Windows<'a, T: 'a> {
+ v: &'a [T],
+ size: usize,
+}
+
+impl<'a, T: 'a> Windows<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+ Self { v: slice, size }
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Clone for Windows<'_, T> {
+ fn clone(&self) -> Self {
+ Windows { v: self.v, size: self.size }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Iterator for Windows<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.size > self.v.len() {
+ None
+ } else {
+ let ret = Some(&self.v[..self.size]);
+ self.v = &self.v[1..];
+ ret
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.size > self.v.len() {
+ (0, Some(0))
+ } else {
+ let size = self.v.len() - self.size + 1;
+ (size, Some(size))
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (end, overflow) = self.size.overflowing_add(n);
+ if end > self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ let nth = &self.v[n..end];
+ self.v = &self.v[n + 1..];
+ Some(nth)
+ }
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ if self.size > self.v.len() {
+ None
+ } else {
+ let start = self.v.len() - self.size;
+ Some(&self.v[start..])
+ }
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ // SAFETY: since the caller guarantees that `i` is in bounds,
+ // which means that `i` cannot overflow an `isize`, and the
+ // slice created by `from_raw_parts` is a subslice of `self.v`
+ // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
+ unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.size > self.v.len() {
+ None
+ } else {
+ let ret = Some(&self.v[self.v.len() - self.size..]);
+ self.v = &self.v[..self.v.len() - 1];
+ ret
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let (end, overflow) = self.v.len().overflowing_sub(n);
+ if end < self.size || overflow {
+ self.v = &[];
+ None
+ } else {
+ let ret = &self.v[end - self.size..end];
+ self.v = &self.v[..end - 1];
+ Some(ret)
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ExactSizeIterator for Windows<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for Windows<'_, T> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T> FusedIterator for Windows<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+/// time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last slice
+/// of the iteration will be the remainder.
+///
+/// This struct is created by the [`chunks`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks(2);
+/// ```
+///
+/// [`chunks`]: ../../std/primitive.slice.html#method.chunks
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Chunks<'a, T: 'a> {
+ v: &'a [T],
+ chunk_size: usize,
+}
+
+impl<'a, T: 'a> Chunks<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+ Self { v: slice, chunk_size: size }
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Clone for Chunks<'_, T> {
+ fn clone(&self) -> Self {
+ Chunks { v: self.v, chunk_size: self.chunk_size }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Iterator for Chunks<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let chunksz = cmp::min(self.v.len(), self.chunk_size);
+ let (fst, snd) = self.v.split_at(chunksz);
+ self.v = snd;
+ Some(fst)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.v.is_empty() {
+ (0, Some(0))
+ } else {
+ let n = self.v.len() / self.chunk_size;
+ let rem = self.v.len() % self.chunk_size;
+ let n = if rem > 0 { n + 1 } else { n };
+ (n, Some(n))
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ let end = match start.checked_add(self.chunk_size) {
+ Some(sum) => cmp::min(self.v.len(), sum),
+ None => self.v.len(),
+ };
+ let nth = &self.v[start..end];
+ self.v = &self.v[end..];
+ Some(nth)
+ }
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
+ Some(&self.v[start..])
+ }
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let start = idx * self.chunk_size;
+ let end = match start.checked_add(self.chunk_size) {
+ None => self.v.len(),
+ Some(end) => cmp::min(end, self.v.len()),
+ };
+ // SAFETY: the caller guarantees that `i` is in bounds,
+ // which means that `start` must be in bounds of the
+ // underlying `self.v` slice, and we made sure that `end`
+ // is also in bounds of `self.v`. Thus, `start` cannot overflow
+ // an `isize`, and the slice constructed by `from_raw_parts`
+ // is a subslice of `self.v` which is guaranteed to be valid
+ // for the lifetime `'a` of `self.v`.
+ unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let remainder = self.v.len() % self.chunk_size;
+ let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
+ let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
+ self.v = fst;
+ Some(snd)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &[];
+ None
+ } else {
+ let start = (len - 1 - n) * self.chunk_size;
+ let end = match start.checked_add(self.chunk_size) {
+ Some(res) => cmp::min(res, self.v.len()),
+ None => self.v.len(),
+ };
+ let nth_back = &self.v[start..end];
+ self.v = &self.v[..start];
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ExactSizeIterator for Chunks<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for Chunks<'_, T> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T> FusedIterator for Chunks<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+/// elements at a time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last slice
+/// of the iteration will be the remainder.
+///
+/// This struct is created by the [`chunks_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_mut(2);
+/// ```
+///
+/// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ChunksMut<'a, T: 'a> {
+ v: &'a mut [T],
+ chunk_size: usize,
+}
+
+impl<'a, T: 'a> ChunksMut<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+ Self { v: slice, chunk_size: size }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Iterator for ChunksMut<'a, T> {
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let sz = cmp::min(self.v.len(), self.chunk_size);
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(sz);
+ self.v = tail;
+ Some(head)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.v.is_empty() {
+ (0, Some(0))
+ } else {
+ let n = self.v.len() / self.chunk_size;
+ let rem = self.v.len() % self.chunk_size;
+ let n = if rem > 0 { n + 1 } else { n };
+ (n, Some(n))
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &mut [];
+ None
+ } else {
+ let end = match start.checked_add(self.chunk_size) {
+ Some(sum) => cmp::min(self.v.len(), sum),
+ None => self.v.len(),
+ };
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(end);
+ let (_, nth) = head.split_at_mut(start);
+ self.v = tail;
+ Some(nth)
+ }
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
+ Some(&mut self.v[start..])
+ }
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let start = idx * self.chunk_size;
+ let end = match start.checked_add(self.chunk_size) {
+ None => self.v.len(),
+ Some(end) => cmp::min(end, self.v.len()),
+ };
+ // SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
+ //
+ // Also note that the caller also guarantees that we're never called
+ // with the same index again, and that no other methods that will
+ // access this subslice are called, so it is valid for the returned
+ // slice to be mutable.
+ unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let remainder = self.v.len() % self.chunk_size;
+ let sz = if remainder != 0 { remainder } else { self.chunk_size };
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (head, tail) = tmp.split_at_mut(tmp_len - sz);
+ self.v = head;
+ Some(tail)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &mut [];
+ None
+ } else {
+ let start = (len - 1 - n) * self.chunk_size;
+ let end = match start.checked_add(self.chunk_size) {
+ Some(res) => cmp::min(res, self.v.len()),
+ None => self.v.len(),
+ };
+ let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+ let (head, nth_back) = temp.split_at_mut(start);
+ self.v = head;
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T> FusedIterator for ChunksMut<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+/// time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last
+/// up to `chunk_size-1` elements will be omitted but can be retrieved from
+/// the [`remainder`] function from the iterator.
+///
+/// This struct is created by the [`chunks_exact`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_exact(2);
+/// ```
+///
+/// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
+/// [`remainder`]: ChunksExact::remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+pub struct ChunksExact<'a, T: 'a> {
+ v: &'a [T],
+ rem: &'a [T],
+ chunk_size: usize,
+}
+
+impl<'a, T> ChunksExact<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+ let rem = slice.len() % chunk_size;
+ let fst_len = slice.len() - rem;
+ // SAFETY: 0 <= fst_len <= slice.len() by construction above
+ let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
+ Self { v: fst, rem: snd, chunk_size }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `chunk_size-1`
+ /// elements.
+ #[stable(feature = "chunks_exact", since = "1.31.0")]
+ pub fn remainder(&self) -> &'a [T] {
+ self.rem
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<T> Clone for ChunksExact<'_, T> {
+ fn clone(&self) -> Self {
+ ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<'a, T> Iterator for ChunksExact<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.chunk_size);
+ self.v = snd;
+ Some(fst)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ let (_, snd) = self.v.split_at(start);
+ self.v = snd;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let start = idx * self.chunk_size;
+ // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
+ unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
+ self.v = fst;
+ Some(snd)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &[];
+ None
+ } else {
+ let start = (len - 1 - n) * self.chunk_size;
+ let end = start + self.chunk_size;
+ let nth_back = &self.v[start..end];
+ self.v = &self.v[..start];
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<T> ExactSizeIterator for ChunksExact<'_, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<T> FusedIterator for ChunksExact<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+/// elements at a time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last up to
+/// `chunk_size-1` elements will be omitted but can be retrieved from the
+/// [`into_remainder`] function from the iterator.
+///
+/// This struct is created by the [`chunks_exact_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.chunks_exact_mut(2);
+/// ```
+///
+/// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut
+/// [`into_remainder`]: ChunksExactMut::into_remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+pub struct ChunksExactMut<'a, T: 'a> {
+ v: &'a mut [T],
+ rem: &'a mut [T],
+ chunk_size: usize,
+}
+
+impl<'a, T> ChunksExactMut<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+ let rem = slice.len() % chunk_size;
+ let fst_len = slice.len() - rem;
+ // SAFETY: 0 <= fst_len <= slice.len() by construction above
+ let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
+ Self { v: fst, rem: snd, chunk_size }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `chunk_size-1`
+ /// elements.
+ #[stable(feature = "chunks_exact", since = "1.31.0")]
+ pub fn into_remainder(self) -> &'a mut [T] {
+ self.rem
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<'a, T> Iterator for ChunksExactMut<'a, T> {
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(self.chunk_size);
+ self.v = tail;
+ Some(head)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &mut [];
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (_, snd) = tmp.split_at_mut(start);
+ self.v = snd;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let start = idx * self.chunk_size;
+ // SAFETY: see comments for `ChunksMut::__iterator_get_unchecked`.
+ unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
+ self.v = head;
+ Some(tail)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &mut [];
+ None
+ } else {
+ let start = (len - 1 - n) * self.chunk_size;
+ let end = start + self.chunk_size;
+ let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+ let (head, nth_back) = temp.split_at_mut(start);
+ self.v = head;
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+impl<T> FusedIterator for ChunksExactMut<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// A windowed iterator over a slice in overlapping chunks (`N` elements at a
+/// time), starting at the beginning of the slice
+///
+/// This struct is created by the [`array_windows`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// #![feature(array_windows)]
+///
+/// let slice = [0, 1, 2, 3];
+/// let iter = slice.array_windows::<2>();
+/// ```
+///
+/// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug, Clone, Copy)]
+#[unstable(feature = "array_windows", issue = "75027")]
+pub struct ArrayWindows<'a, T: 'a, const N: usize> {
+ slice_head: *const T,
+ num: usize,
+ marker: PhantomData<&'a [T; N]>,
+}
+
+impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T]) -> Self {
+ let num_windows = slice.len().saturating_sub(N - 1);
+ Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
+ }
+}
+
+#[unstable(feature = "array_windows", issue = "75027")]
+impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
+ type Item = &'a [T; N];
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.num == 0 {
+ return None;
+ }
+ // SAFETY:
+ // This is safe because it's indexing into a slice guaranteed to be length > N.
+ let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
+ // SAFETY: Guaranteed that there are at least 1 item remaining otherwise
+ // earlier branch would've been hit
+ self.slice_head = unsafe { self.slice_head.add(1) };
+
+ self.num -= 1;
+ Some(ret)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.num, Some(self.num))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.num
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ if self.num <= n {
+ self.num = 0;
+ return None;
+ }
+ // SAFETY:
+ // This is safe because it's indexing into a slice guaranteed to be length > N.
+ let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
+ // SAFETY: Guaranteed that there are at least n items remaining
+ self.slice_head = unsafe { self.slice_head.add(n + 1) };
+
+ self.num -= n + 1;
+ Some(ret)
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.nth(self.num.checked_sub(1)?)
+ }
+}
+
+#[unstable(feature = "array_windows", issue = "75027")]
+impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T; N]> {
+ if self.num == 0 {
+ return None;
+ }
+ // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
+ let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
+ self.num -= 1;
+ Some(ret)
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
+ if self.num <= n {
+ self.num = 0;
+ return None;
+ }
+ // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
+ let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
+ self.num -= n + 1;
+ Some(ret)
+ }
+}
+
+#[unstable(feature = "array_windows", issue = "75027")]
+impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
+ fn is_empty(&self) -> bool {
+ self.num == 0
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) chunks (`N` elements at a
+/// time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last
+/// up to `N-1` elements will be omitted but can be retrieved from
+/// the [`remainder`] function from the iterator.
+///
+/// This struct is created by the [`array_chunks`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// #![feature(array_chunks)]
+///
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.array_chunks::<2>();
+/// ```
+///
+/// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
+/// [`remainder`]: ArrayChunks::remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+pub struct ArrayChunks<'a, T: 'a, const N: usize> {
+ iter: Iter<'a, [T; N]>,
+ rem: &'a [T],
+}
+
+impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T]) -> Self {
+ let len = slice.len() / N;
+ let (fst, snd) = slice.split_at(len * N);
+ // SAFETY: We cast a slice of `len * N` elements into
+ // a slice of `len` many `N` elements chunks.
+ let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
+
+ Self { iter: array_slice.iter(), rem: snd }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `N-1`
+ /// elements.
+ #[unstable(feature = "array_chunks", issue = "74985")]
+ pub fn remainder(&self) -> &'a [T] {
+ self.rem
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<T, const N: usize> Clone for ArrayChunks<'_, T, N> {
+ fn clone(&self) -> Self {
+ ArrayChunks { iter: self.iter.clone(), rem: self.rem }
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
+ type Item = &'a [T; N];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T; N]> {
+ self.iter.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.iter.nth(n)
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ self.iter.last()
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
+ // SAFETY: The safety guarantees of `__iterator_get_unchecked` are
+ // transferred to the caller.
+ unsafe { self.iter.__iterator_get_unchecked(i) }
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunks<'a, T, N> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T; N]> {
+ self.iter.next_back()
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ self.iter.nth_back(n)
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<T, const N: usize> ExactSizeIterator for ArrayChunks<'_, T, N> {
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T, const N: usize> TrustedLen for ArrayChunks<'_, T, N> {}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
+
+#[doc(hidden)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`N` elements
+/// at a time), starting at the beginning of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last
+/// up to `N-1` elements will be omitted but can be retrieved from
+/// the [`into_remainder`] function from the iterator.
+///
+/// This struct is created by the [`array_chunks_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// #![feature(array_chunks)]
+///
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.array_chunks_mut::<2>();
+/// ```
+///
+/// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut
+/// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
+ iter: IterMut<'a, [T; N]>,
+ rem: &'a mut [T],
+}
+
+impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T]) -> Self {
+ let len = slice.len() / N;
+ let (fst, snd) = slice.split_at_mut(len * N);
+ // SAFETY: We cast a slice of `len * N` elements into
+ // a slice of `len` many `N` elements chunks.
+ unsafe {
+ let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len);
+ Self { iter: array_slice.iter_mut(), rem: snd }
+ }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `N-1`
+ /// elements.
+ #[unstable(feature = "array_chunks", issue = "74985")]
+ pub fn into_remainder(self) -> &'a mut [T] {
+ self.rem
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> {
+ type Item = &'a mut [T; N];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T; N]> {
+ self.iter.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.iter.nth(n)
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ self.iter.last()
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a mut [T; N] {
+ // SAFETY: The safety guarantees of `__iterator_get_unchecked` are transferred to
+ // the caller.
+ unsafe { self.iter.__iterator_get_unchecked(i) }
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunksMut<'a, T, N> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T; N]> {
+ self.iter.next_back()
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ self.iter.nth_back(n)
+ }
+}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<T, const N: usize> ExactSizeIterator for ArrayChunksMut<'_, T, N> {
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T, const N: usize> TrustedLen for ArrayChunksMut<'_, T, N> {}
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+impl<T, const N: usize> FusedIterator for ArrayChunksMut<'_, T, N> {}
+
+#[doc(hidden)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T, N> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+/// time), starting at the end of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last slice
+/// of the iteration will be the remainder.
+///
+/// This struct is created by the [`rchunks`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks(2);
+/// ```
+///
+/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rchunks", since = "1.31.0")]
+pub struct RChunks<'a, T: 'a> {
+ v: &'a [T],
+ chunk_size: usize,
+}
+
+impl<'a, T: 'a> RChunks<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+ Self { v: slice, chunk_size: size }
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> Clone for RChunks<'_, T> {
+ fn clone(&self) -> Self {
+ RChunks { v: self.v, chunk_size: self.chunk_size }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> Iterator for RChunks<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let chunksz = cmp::min(self.v.len(), self.chunk_size);
+ let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
+ self.v = fst;
+ Some(snd)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.v.is_empty() {
+ (0, Some(0))
+ } else {
+ let n = self.v.len() / self.chunk_size;
+ let rem = self.v.len() % self.chunk_size;
+ let n = if rem > 0 { n + 1 } else { n };
+ (n, Some(n))
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (end, overflow) = n.overflowing_mul(self.chunk_size);
+ if end >= self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ // Can't underflow because of the check above
+ let end = self.v.len() - end;
+ let start = match end.checked_sub(self.chunk_size) {
+ Some(sum) => sum,
+ None => 0,
+ };
+ let nth = &self.v[start..end];
+ self.v = &self.v[0..start];
+ Some(nth)
+ }
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let rem = self.v.len() % self.chunk_size;
+ let end = if rem == 0 { self.chunk_size } else { rem };
+ Some(&self.v[0..end])
+ }
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let end = self.v.len() - idx * self.chunk_size;
+ let start = match end.checked_sub(self.chunk_size) {
+ None => 0,
+ Some(start) => start,
+ };
+ // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
+ unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let remainder = self.v.len() % self.chunk_size;
+ let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
+ let (fst, snd) = self.v.split_at(chunksz);
+ self.v = snd;
+ Some(fst)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &[];
+ None
+ } else {
+ // can't underflow because `n < len`
+ let offset_from_end = (len - 1 - n) * self.chunk_size;
+ let end = self.v.len() - offset_from_end;
+ let start = end.saturating_sub(self.chunk_size);
+ let nth_back = &self.v[start..end];
+ self.v = &self.v[end..];
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> ExactSizeIterator for RChunks<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for RChunks<'_, T> {}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> FusedIterator for RChunks<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+/// elements at a time), starting at the end of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last slice
+/// of the iteration will be the remainder.
+///
+/// This struct is created by the [`rchunks_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_mut(2);
+/// ```
+///
+/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rchunks", since = "1.31.0")]
+pub struct RChunksMut<'a, T: 'a> {
+ v: &'a mut [T],
+ chunk_size: usize,
+}
+
+impl<'a, T: 'a> RChunksMut<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+ Self { v: slice, chunk_size: size }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> Iterator for RChunksMut<'a, T> {
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let sz = cmp::min(self.v.len(), self.chunk_size);
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (head, tail) = tmp.split_at_mut(tmp_len - sz);
+ self.v = head;
+ Some(tail)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.v.is_empty() {
+ (0, Some(0))
+ } else {
+ let n = self.v.len() / self.chunk_size;
+ let rem = self.v.len() % self.chunk_size;
+ let n = if rem > 0 { n + 1 } else { n };
+ (n, Some(n))
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+ let (end, overflow) = n.overflowing_mul(self.chunk_size);
+ if end >= self.v.len() || overflow {
+ self.v = &mut [];
+ None
+ } else {
+ // Can't underflow because of the check above
+ let end = self.v.len() - end;
+ let start = match end.checked_sub(self.chunk_size) {
+ Some(sum) => sum,
+ None => 0,
+ };
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(start);
+ let (nth, _) = tail.split_at_mut(end - start);
+ self.v = head;
+ Some(nth)
+ }
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let rem = self.v.len() % self.chunk_size;
+ let end = if rem == 0 { self.chunk_size } else { rem };
+ Some(&mut self.v[0..end])
+ }
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let end = self.v.len() - idx * self.chunk_size;
+ let start = match end.checked_sub(self.chunk_size) {
+ None => 0,
+ Some(start) => start,
+ };
+ // SAFETY: see comments for `RChunks::__iterator_get_unchecked` and
+ // `ChunksMut::__iterator_get_unchecked`
+ unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.v.is_empty() {
+ None
+ } else {
+ let remainder = self.v.len() % self.chunk_size;
+ let sz = if remainder != 0 { remainder } else { self.chunk_size };
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(sz);
+ self.v = tail;
+ Some(head)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &mut [];
+ None
+ } else {
+ // can't underflow because `n < len`
+ let offset_from_end = (len - 1 - n) * self.chunk_size;
+ let end = self.v.len() - offset_from_end;
+ let start = end.saturating_sub(self.chunk_size);
+ let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+ let (_, nth_back) = tmp.split_at_mut(start);
+ self.v = tail;
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> FusedIterator for RChunksMut<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+/// time), starting at the end of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last
+/// up to `chunk_size-1` elements will be omitted but can be retrieved from
+/// the [`remainder`] function from the iterator.
+///
+/// This struct is created by the [`rchunks_exact`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_exact(2);
+/// ```
+///
+/// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
+/// [`remainder`]: ChunksExact::remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rchunks", since = "1.31.0")]
+pub struct RChunksExact<'a, T: 'a> {
+ v: &'a [T],
+ rem: &'a [T],
+ chunk_size: usize,
+}
+
+impl<'a, T> RChunksExact<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+ let rem = slice.len() % chunk_size;
+ // SAFETY: 0 <= rem <= slice.len() by construction above
+ let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
+ Self { v: snd, rem: fst, chunk_size }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `chunk_size-1`
+ /// elements.
+ #[stable(feature = "rchunks", since = "1.31.0")]
+ pub fn remainder(&self) -> &'a [T] {
+ self.rem
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> Clone for RChunksExact<'a, T> {
+ fn clone(&self) -> RChunksExact<'a, T> {
+ RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> Iterator for RChunksExact<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
+ self.v = fst;
+ Some(snd)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (end, overflow) = n.overflowing_mul(self.chunk_size);
+ if end >= self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ let (fst, _) = self.v.split_at(self.v.len() - end);
+ self.v = fst;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let end = self.v.len() - idx * self.chunk_size;
+ let start = end - self.chunk_size;
+ // SAFETY:
+ // SAFETY: mostmy identical to `Chunks::__iterator_get_unchecked`.
+ unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.chunk_size);
+ self.v = snd;
+ Some(fst)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &[];
+ None
+ } else {
+ // now that we know that `n` corresponds to a chunk,
+ // none of these operations can underflow/overflow
+ let offset = (len - n) * self.chunk_size;
+ let start = self.v.len() - offset;
+ let end = start + self.chunk_size;
+ let nth_back = &self.v[start..end];
+ self.v = &self.v[end..];
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> FusedIterator for RChunksExact<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+/// elements at a time), starting at the end of the slice.
+///
+/// When the slice len is not evenly divided by the chunk size, the last up to
+/// `chunk_size-1` elements will be omitted but can be retrieved from the
+/// [`into_remainder`] function from the iterator.
+///
+/// This struct is created by the [`rchunks_exact_mut`] method on [slices].
+///
+/// # Example
+///
+/// ```
+/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
+/// let iter = slice.rchunks_exact_mut(2);
+/// ```
+///
+/// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
+/// [`into_remainder`]: ChunksExactMut::into_remainder
+/// [slices]: ../../std/primitive.slice.html
+#[derive(Debug)]
+#[stable(feature = "rchunks", since = "1.31.0")]
+pub struct RChunksExactMut<'a, T: 'a> {
+ v: &'a mut [T],
+ rem: &'a mut [T],
+ chunk_size: usize,
+}
+
+impl<'a, T> RChunksExactMut<'a, T> {
+ #[inline]
+ pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+ let rem = slice.len() % chunk_size;
+ // SAFETY: 0 <= rem <= slice.len() by construction above
+ let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
+ Self { v: snd, rem: fst, chunk_size }
+ }
+
+ /// Returns the remainder of the original slice that is not going to be
+ /// returned by the iterator. The returned slice has at most `chunk_size-1`
+ /// elements.
+ #[stable(feature = "rchunks", since = "1.31.0")]
+ pub fn into_remainder(self) -> &'a mut [T] {
+ self.rem
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> Iterator for RChunksExactMut<'a, T> {
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
+ self.v = head;
+ Some(tail)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+ let (end, overflow) = n.overflowing_mul(self.chunk_size);
+ if end >= self.v.len() || overflow {
+ self.v = &mut [];
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (fst, _) = tmp.split_at_mut(tmp_len - end);
+ self.v = fst;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ let end = self.v.len() - idx * self.chunk_size;
+ let start = end - self.chunk_size;
+ // SAFETY: see comments for `RChunksMut::__iterator_get_unchecked`.
+ unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(self.chunk_size);
+ self.v = tail;
+ Some(head)
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.len();
+ if n >= len {
+ self.v = &mut [];
+ None
+ } else {
+ // now that we know that `n` corresponds to a chunk,
+ // none of these operations can underflow/overflow
+ let offset = (len - n) * self.chunk_size;
+ let start = self.v.len() - offset;
+ let end = start + self.chunk_size;
+ let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+ let (_, nth_back) = tmp.split_at_mut(start);
+ self.v = tail;
+ Some(nth_back)
+ }
+ }
+}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+impl<T> FusedIterator for RChunksExactMut<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
new file mode 100644
index 0000000..457b2a3
--- /dev/null
+++ b/library/core/src/slice/iter/macros.rs
@@ -0,0 +1,407 @@
+//! Macros used by iterators of slice.
+
+// Inlining is_empty and len makes a huge performance difference
+macro_rules! is_empty {
+ // The way we encode the length of a ZST iterator, this works both for ZST
+ // and non-ZST.
+ ($self: ident) => {
+ $self.ptr.as_ptr() as *const T == $self.end
+ };
+}
+
+// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
+// unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
+macro_rules! len {
+ ($self: ident) => {{
+ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
+
+ let start = $self.ptr;
+ let size = size_from_ptr(start.as_ptr());
+ if size == 0 {
+ // This _cannot_ use `unchecked_sub` because we depend on wrapping
+ // to represent the length of long ZST slice iterators.
+ ($self.end as usize).wrapping_sub(start.as_ptr() as usize)
+ } else {
+ // We know that `start <= end`, so can do better than `offset_from`,
+ // which needs to deal in signed. By setting appropriate flags here
+ // we can tell LLVM this, which helps it remove bounds checks.
+ // SAFETY: By the type invariant, `start <= end`
+ let diff = unsafe { unchecked_sub($self.end as usize, start.as_ptr() as usize) };
+ // By also telling LLVM that the pointers are apart by an exact
+ // multiple of the type size, it can optimize `len() == 0` down to
+ // `start == end` instead of `(end - start) < size`.
+ // SAFETY: By the type invariant, the pointers are aligned so the
+ // distance between them must be a multiple of pointee size
+ unsafe { exact_div(diff, size) }
+ }
+ }};
+}
+
+// The shared definition of the `Iter` and `IterMut` iterators
+macro_rules! iterator {
+ (
+ struct $name:ident -> $ptr:ty,
+ $elem:ty,
+ $raw_mut:tt,
+ {$( $mut_:tt )?},
+ {$($extra:tt)*}
+ ) => {
+ // Returns the first element and moves the start of the iterator forwards by 1.
+ // Greatly improves performance compared to an inlined function. The iterator
+ // must not be empty.
+ macro_rules! next_unchecked {
+ ($self: ident) => {& $( $mut_ )? *$self.post_inc_start(1)}
+ }
+
+ // Returns the last element and moves the end of the iterator backwards by 1.
+ // Greatly improves performance compared to an inlined function. The iterator
+ // must not be empty.
+ macro_rules! next_back_unchecked {
+ ($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)}
+ }
+
+ // Shrinks the iterator when T is a ZST, by moving the end of the iterator
+ // backwards by `n`. `n` must not exceed `self.len()`.
+ macro_rules! zst_shrink {
+ ($self: ident, $n: ident) => {
+ $self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
+ }
+ }
+
+ impl<'a, T> $name<'a, T> {
+ // Helper function for creating a slice from the iterator.
+ #[inline(always)]
+ fn make_slice(&self) -> &'a [T] {
+ // SAFETY: the iterator was created from a slice with pointer
+ // `self.ptr` and length `len!(self)`. This guarantees that all
+ // the prerequisites for `from_raw_parts` are fulfilled.
+ unsafe { from_raw_parts(self.ptr.as_ptr(), len!(self)) }
+ }
+
+ // Helper function for moving the start of the iterator forwards by `offset` elements,
+ // returning the old start.
+ // Unsafe because the offset must not exceed `self.len()`.
+ #[inline(always)]
+ unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
+ if mem::size_of::<T>() == 0 {
+ zst_shrink!(self, offset);
+ self.ptr.as_ptr()
+ } else {
+ let old = self.ptr.as_ptr();
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
+ // so this new pointer is inside `self` and thus guaranteed to be non-null.
+ self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
+ old
+ }
+ }
+
+ // Helper function for moving the end of the iterator backwards by `offset` elements,
+ // returning the new end.
+ // Unsafe because the offset must not exceed `self.len()`.
+ #[inline(always)]
+ unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
+ if mem::size_of::<T>() == 0 {
+ zst_shrink!(self, offset);
+ self.ptr.as_ptr()
+ } else {
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
+ // which is guaranteed to not overflow an `isize`. Also, the resulting pointer
+ // is in bounds of `slice`, which fulfills the other requirements for `offset`.
+ self.end = unsafe { self.end.offset(-offset) };
+ self.end
+ }
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T> ExactSizeIterator for $name<'_, T> {
+ #[inline(always)]
+ fn len(&self) -> usize {
+ len!(self)
+ }
+
+ #[inline(always)]
+ fn is_empty(&self) -> bool {
+ is_empty!(self)
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<'a, T> Iterator for $name<'a, T> {
+ type Item = $elem;
+
+ #[inline]
+ fn next(&mut self) -> Option<$elem> {
+ // could be implemented with slices, but this avoids bounds checks
+
+ // SAFETY: `assume` calls are safe since a slice's start pointer
+ // must be non-null, and slices over non-ZSTs must also have a
+ // non-null end pointer. The call to `next_unchecked!` is safe
+ // since we check if the iterator is empty first.
+ unsafe {
+ assume(!self.ptr.as_ptr().is_null());
+ if mem::size_of::<T>() != 0 {
+ assume(!self.end.is_null());
+ }
+ if is_empty!(self) {
+ None
+ } else {
+ Some(next_unchecked!(self))
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let exact = len!(self);
+ (exact, Some(exact))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ len!(self)
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<$elem> {
+ if n >= len!(self) {
+ // This iterator is now empty.
+ if mem::size_of::<T>() == 0 {
+ // We have to do it this way as `ptr` may never be 0, but `end`
+ // could be (due to wrapping).
+ self.end = self.ptr.as_ptr();
+ } else {
+ // SAFETY: end can't be 0 if T isn't ZST because ptr isn't 0 and end >= ptr
+ unsafe {
+ self.ptr = NonNull::new_unchecked(self.end as *mut T);
+ }
+ }
+ return None;
+ }
+ // SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
+ unsafe {
+ self.post_inc_start(n as isize);
+ Some(next_unchecked!(self))
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<$elem> {
+ self.next_back()
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile.
+ #[inline]
+ fn for_each<F>(mut self, mut f: F)
+ where
+ Self: Sized,
+ F: FnMut(Self::Item),
+ {
+ while let Some(x) = self.next() {
+ f(x);
+ }
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile.
+ #[inline]
+ fn all<F>(&mut self, mut f: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
+ {
+ while let Some(x) = self.next() {
+ if !f(x) {
+ return false;
+ }
+ }
+ true
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile.
+ #[inline]
+ fn any<F>(&mut self, mut f: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
+ {
+ while let Some(x) = self.next() {
+ if f(x) {
+ return true;
+ }
+ }
+ false
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile.
+ #[inline]
+ fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
+ where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
+ {
+ while let Some(x) = self.next() {
+ if predicate(&x) {
+ return Some(x);
+ }
+ }
+ None
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile.
+ #[inline]
+ fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
+ where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
+ {
+ while let Some(x) = self.next() {
+ if let Some(y) = f(x) {
+ return Some(y);
+ }
+ }
+ None
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile. Also, the `assume` avoids a bounds check.
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
+ {
+ let n = len!(self);
+ let mut i = 0;
+ while let Some(x) = self.next() {
+ if predicate(x) {
+ // SAFETY: we are guaranteed to be in bounds by the loop invariant:
+ // when `i >= n`, `self.next()` returns `None` and the loop breaks.
+ unsafe { assume(i < n) };
+ return Some(i);
+ }
+ i += 1;
+ }
+ None
+ }
+
+ // We override the default implementation, which uses `try_fold`,
+ // because this simple implementation generates less LLVM IR and is
+ // faster to compile. Also, the `assume` avoids a bounds check.
+ #[inline]
+ fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
+ P: FnMut(Self::Item) -> bool,
+ Self: Sized + ExactSizeIterator + DoubleEndedIterator
+ {
+ let n = len!(self);
+ let mut i = n;
+ while let Some(x) = self.next_back() {
+ i -= 1;
+ if predicate(x) {
+ // SAFETY: `i` must be lower than `n` since it starts at `n`
+ // and is only decreasing.
+ unsafe { assume(i < n) };
+ return Some(i);
+ }
+ }
+ None
+ }
+
+ #[doc(hidden)]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+ // SAFETY: the caller must guarantee that `i` is in bounds of
+ // the underlying slice, so `i` cannot overflow an `isize`, and
+ // the returned references is guaranteed to refer to an element
+ // of the slice and thus guaranteed to be valid.
+ //
+ // Also note that the caller also guarantees that we're never
+ // called with the same index again, and that no other methods
+ // that will access this subslice are called, so it is valid
+ // for the returned reference to be mutable in the case of
+ // `IterMut`
+ unsafe { & $( $mut_ )? * self.ptr.as_ptr().add(idx) }
+ }
+
+ $($extra)*
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<'a, T> DoubleEndedIterator for $name<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<$elem> {
+ // could be implemented with slices, but this avoids bounds checks
+
+ // SAFETY: `assume` calls are safe since a slice's start pointer must be non-null,
+ // and slices over non-ZSTs must also have a non-null end pointer.
+ // The call to `next_back_unchecked!` is safe since we check if the iterator is
+ // empty first.
+ unsafe {
+ assume(!self.ptr.as_ptr().is_null());
+ if mem::size_of::<T>() != 0 {
+ assume(!self.end.is_null());
+ }
+ if is_empty!(self) {
+ None
+ } else {
+ Some(next_back_unchecked!(self))
+ }
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<$elem> {
+ if n >= len!(self) {
+ // This iterator is now empty.
+ self.end = self.ptr.as_ptr();
+ return None;
+ }
+ // SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
+ unsafe {
+ self.pre_dec_end(n as isize);
+ Some(next_back_unchecked!(self))
+ }
+ }
+ }
+
+ #[stable(feature = "fused", since = "1.26.0")]
+ impl<T> FusedIterator for $name<'_, T> {}
+
+ #[unstable(feature = "trusted_len", issue = "37572")]
+ unsafe impl<T> TrustedLen for $name<'_, T> {}
+ }
+}
+
+macro_rules! forward_iterator {
+ ($name:ident: $elem:ident, $iter_of:ty) => {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<'a, $elem, P> Iterator for $name<'a, $elem, P>
+ where
+ P: FnMut(&T) -> bool,
+ {
+ type Item = $iter_of;
+
+ #[inline]
+ fn next(&mut self) -> Option<$iter_of> {
+ self.inner.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+ }
+
+ #[stable(feature = "fused", since = "1.26.0")]
+ impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P> where P: FnMut(&T) -> bool {}
+ };
+}
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index 3b13ed5..0c0f175 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -12,6 +12,7 @@
// Use truncation.
const LO_USIZE: usize = LO_U64 as usize;
const HI_USIZE: usize = HI_U64 as usize;
+const USIZE_BYTES: usize = mem::size_of::<usize>();
/// Returns `true` if `x` contains any zero byte.
///
@@ -38,19 +39,29 @@
}
/// Returns the first index matching the byte `x` in `text`.
+#[inline]
pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
+ // Fast path for small slices
+ if text.len() < 2 * USIZE_BYTES {
+ return text.iter().position(|elt| *elt == x);
+ }
+
+ memchr_general_case(x, text)
+}
+
+fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
// Scan for a single byte value by reading two `usize` words at a time.
//
// Split `text` in three parts
// - unaligned initial part, before the first word aligned address in text
// - body, scan by 2 words at a time
// - the last remaining part, < 2 word size
- let len = text.len();
- let ptr = text.as_ptr();
- let usize_bytes = mem::size_of::<usize>();
// search up to an aligned boundary
- let mut offset = ptr.align_offset(usize_bytes);
+ let len = text.len();
+ let ptr = text.as_ptr();
+ let mut offset = ptr.align_offset(USIZE_BYTES);
+
if offset > 0 {
offset = cmp::min(offset, len);
if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
@@ -60,22 +71,19 @@
// search the body of the text
let repeated_x = repeat_byte(x);
+ while offset <= len - 2 * USIZE_BYTES {
+ unsafe {
+ let u = *(ptr.add(offset) as *const usize);
+ let v = *(ptr.add(offset + USIZE_BYTES) as *const usize);
- if len >= 2 * usize_bytes {
- while offset <= len - 2 * usize_bytes {
- unsafe {
- let u = *(ptr.add(offset) as *const usize);
- let v = *(ptr.add(offset + usize_bytes) as *const usize);
-
- // break if there is a matching byte
- let zu = contains_zero_byte(u ^ repeated_x);
- let zv = contains_zero_byte(v ^ repeated_x);
- if zu || zv {
- break;
- }
+ // break if there is a matching byte
+ let zu = contains_zero_byte(u ^ repeated_x);
+ let zv = contains_zero_byte(v ^ repeated_x);
+ if zu || zv {
+ break;
}
- offset += usize_bytes * 2;
}
+ offset += USIZE_BYTES * 2;
}
// Find the byte after the point the body loop stopped.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index e7eed43..b1ca093 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -8,31 +8,13 @@
#![stable(feature = "rust1", since = "1.0.0")]
-// How this module is organized.
-//
-// The library infrastructure for slices is fairly messy. There's
-// a lot of stuff defined here. Let's keep it clean.
-//
-// The layout of this file is thus:
-//
-// * Inherent methods. This is where most of the slice API resides.
-// * Implementations of a few common traits with important slice ops.
-// * Definitions of a bunch of iterators.
-// * Free functions.
-// * The `raw` and `bytes` submodules.
-// * Boilerplate trait implementations.
-
-use crate::cmp;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
-use crate::fmt;
-use crate::intrinsics::{assume, exact_div, is_aligned_and_not_null, unchecked_sub};
-use crate::iter::*;
-use crate::marker::{self, Copy, Send, Sized, Sync};
+use crate::marker::Copy;
use crate::mem;
-use crate::ops::{self, FnMut, Range};
+use crate::ops::{FnMut, Range, RangeBounds};
use crate::option::Option;
use crate::option::Option::{None, Some};
-use crate::ptr::{self, NonNull};
+use crate::ptr;
use crate::result::Result;
use crate::result::Result::{Err, Ok};
@@ -44,12 +26,54 @@
/// Pure rust memchr implementation, taken from rust-memchr
pub mod memchr;
+mod ascii;
+mod cmp;
+mod index;
+mod iter;
+mod raw;
mod rotate;
mod sort;
-//
-// Extension traits
-//
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{Chunks, ChunksMut, Windows};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{Iter, IterMut};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{RSplitN, RSplitNMut, Split, SplitMut, SplitN, SplitNMut};
+
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+pub use iter::{RSplit, RSplitMut};
+
+#[stable(feature = "chunks_exact", since = "1.31.0")]
+pub use iter::{ChunksExact, ChunksExactMut};
+
+#[stable(feature = "rchunks", since = "1.31.0")]
+pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
+
+#[unstable(feature = "array_chunks", issue = "74985")]
+pub use iter::{ArrayChunks, ArrayChunksMut};
+
+#[unstable(feature = "array_windows", issue = "75027")]
+pub use iter::ArrayWindows;
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+pub use iter::{SplitInclusive, SplitInclusiveMut};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use raw::{from_raw_parts, from_raw_parts_mut};
+
+#[stable(feature = "from_ref", since = "1.28.0")]
+pub use raw::{from_mut, from_ref};
+
+// This function is public only because there is no other way to unit test heapsort.
+#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
+pub use sort::heapsort;
+
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
+pub use index::SliceIndex;
+
+#[unstable(feature = "slice_check_range", issue = "76393")]
+pub use index::check_range;
#[lang = "slice"]
#[cfg(not(test))]
@@ -66,7 +90,6 @@
#[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
- #[allow(unused_attributes)]
#[allow_internal_unstable(const_fn_union)]
pub const fn len(&self) -> usize {
// SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
@@ -288,10 +311,12 @@
/// Returns a reference to an element or subslice, without doing bounds
/// checking.
///
- /// This is generally not recommended, use with caution!
+ /// For a safe alternative see [`get`].
+ ///
+ /// # Safety
+ ///
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
- /// For a safe alternative see [`get`].
///
/// [`get`]: #method.get
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -320,10 +345,12 @@
/// Returns a mutable reference to an element or subslice, without doing
/// bounds checking.
///
- /// This is generally not recommended, use with caution!
+ /// For a safe alternative see [`get_mut`].
+ ///
+ /// # Safety
+ ///
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
- /// For a safe alternative see [`get_mut`].
///
/// [`get_mut`]: #method.get_mut
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -406,8 +433,9 @@
/// assert_eq!(x, &[3, 4, 6]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[inline]
- pub fn as_mut_ptr(&mut self) -> *mut T {
+ pub const fn as_mut_ptr(&mut self) -> *mut T {
self as *mut [T] as *mut T
}
@@ -430,8 +458,6 @@
/// element of this slice:
///
/// ```
- /// #![feature(slice_ptr_range)]
- ///
/// let a = [1, 2, 3];
/// let x = &a[1] as *const _;
/// let y = &5 as *const _;
@@ -441,9 +467,10 @@
/// ```
///
/// [`as_ptr`]: #method.as_ptr
- #[unstable(feature = "slice_ptr_range", issue = "65807")]
+ #[stable(feature = "slice_ptr_range", since = "1.48.0")]
+ #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[inline]
- pub fn as_ptr_range(&self) -> Range<*const T> {
+ pub const fn as_ptr_range(&self) -> Range<*const T> {
let start = self.as_ptr();
// SAFETY: The `add` here is safe, because:
//
@@ -482,9 +509,10 @@
/// common in C++.
///
/// [`as_mut_ptr`]: #method.as_mut_ptr
- #[unstable(feature = "slice_ptr_range", issue = "65807")]
+ #[stable(feature = "slice_ptr_range", since = "1.48.0")]
+ #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[inline]
- pub fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
+ pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
let start = self.as_mut_ptr();
// SAFETY: See as_ptr_range() above for why `add` here is safe.
let end = unsafe { start.add(self.len()) };
@@ -651,34 +679,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
- let ptr = self.as_ptr();
- // SAFETY: There are several things here:
- //
- // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
- // reference thus it is non-NUL and safe to use and pass to
- // `NonNull::new_unchecked` .
- //
- // Adding `self.len()` to the starting pointer gives a pointer
- // at the end of `self`. `end` will never be dereferenced, only checked
- // for direct pointer equality with `ptr` to check if the iterator is
- // done.
- //
- // In the case of a ZST, the end pointer is just the start pointer plus
- // the length, to also allows for the fast `ptr == end` check.
- //
- // See the `next_unchecked!` and `is_empty!` macros as well as the
- // `post_inc_start` method for more informations.
- unsafe {
- assume(!ptr.is_null());
-
- let end = if mem::size_of::<T>() == 0 {
- (ptr as *const u8).wrapping_add(self.len()) as *const T
- } else {
- ptr.add(self.len())
- };
-
- Iter { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: marker::PhantomData }
- }
+ Iter::new(self)
}
/// Returns an iterator that allows modifying each value.
@@ -695,34 +696,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
- let ptr = self.as_mut_ptr();
- // SAFETY: There are several things here:
- //
- // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
- // reference thus it is non-NUL and safe to use and pass to
- // `NonNull::new_unchecked` .
- //
- // Adding `self.len()` to the starting pointer gives a pointer
- // at the end of `self`. `end` will never be dereferenced, only checked
- // for direct pointer equality with `ptr` to check if the iterator is
- // done.
- //
- // In the case of a ZST, the end pointer is just the start pointer plus
- // the length, to also allows for the fast `ptr == end` check.
- //
- // See the `next_unchecked!` and `is_empty!` macros as well as the
- // `post_inc_start` method for more informations.
- unsafe {
- assume(!ptr.is_null());
-
- let end = if mem::size_of::<T>() == 0 {
- (ptr as *mut u8).wrapping_add(self.len()) as *mut T
- } else {
- ptr.add(self.len())
- };
-
- IterMut { ptr: NonNull::new_unchecked(ptr), end, _marker: marker::PhantomData }
- }
+ IterMut::new(self)
}
/// Returns an iterator over all contiguous windows of length
@@ -755,7 +729,7 @@
#[inline]
pub fn windows(&self, size: usize) -> Windows<'_, T> {
assert_ne!(size, 0);
- Windows { v: self, size }
+ Windows::new(self, size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -789,7 +763,7 @@
#[inline]
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
assert_ne!(chunk_size, 0);
- Chunks { v: self, chunk_size }
+ Chunks::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -827,7 +801,7 @@
#[inline]
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
assert_ne!(chunk_size, 0);
- ChunksMut { v: self, chunk_size }
+ ChunksMut::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -864,10 +838,7 @@
#[inline]
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
assert_ne!(chunk_size, 0);
- let rem = self.len() % chunk_size;
- let len = self.len() - rem;
- let (fst, snd) = self.split_at(len);
- ChunksExact { v: fst, rem: snd, chunk_size }
+ ChunksExact::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -909,18 +880,15 @@
#[inline]
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
assert_ne!(chunk_size, 0);
- let rem = self.len() % chunk_size;
- let len = self.len() - rem;
- let (fst, snd) = self.split_at_mut(len);
- ChunksExactMut { v: fst, rem: snd, chunk_size }
+ ChunksExactMut::new(self, chunk_size)
}
/// Returns an iterator over `N` elements of the slice at a time, starting at the
/// beginning of the slice.
///
- /// The chunks are slices and do not overlap. If `N` does not divide the length of the
- /// slice, then the last up to `N-1` elements will be omitted and can be retrieved
- /// from the `remainder` function of the iterator.
+ /// The chunks are array references and do not overlap. If `N` does not divide the
+ /// length of the slice, then the last up to `N-1` elements will be omitted and can be
+ /// retrieved from the `remainder` function of the iterator.
///
/// This method is the const generic equivalent of [`chunks_exact`].
///
@@ -946,12 +914,75 @@
#[inline]
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
assert_ne!(N, 0);
- let len = self.len() / N;
- let (fst, snd) = self.split_at(len * N);
- // SAFETY: We cast a slice of `len * N` elements into
- // a slice of `len` many `N` elements chunks.
- let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
- ArrayChunks { iter: array_slice.iter(), rem: snd }
+ ArrayChunks::new(self)
+ }
+
+ /// Returns an iterator over `N` elements of the slice at a time, starting at the
+ /// beginning of the slice.
+ ///
+ /// The chunks are mutable array references and do not overlap. If `N` does not divide
+ /// the length of the slice, then the last up to `N-1` elements will be omitted and
+ /// can be retrieved from the `into_remainder` function of the iterator.
+ ///
+ /// This method is the const generic equivalent of [`chunks_exact_mut`].
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(array_chunks)]
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// for chunk in v.array_chunks_mut() {
+ /// *chunk = [count; 2];
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
+ /// ```
+ ///
+ /// [`chunks_exact_mut`]: #method.chunks_exact_mut
+ #[unstable(feature = "array_chunks", issue = "74985")]
+ #[inline]
+ pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
+ assert_ne!(N, 0);
+ ArrayChunksMut::new(self)
+ }
+
+ /// Returns an iterator over overlapping windows of `N` elements of a slice,
+ /// starting at the beginning of the slice.
+ ///
+ /// This is the const generic equivalent of [`windows`].
+ ///
+ /// If `N` is greater than the size of the slice, it will return no windows.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(array_windows)]
+ /// let slice = [0, 1, 2, 3];
+ /// let mut iter = slice.array_windows();
+ /// assert_eq!(iter.next().unwrap(), &[0, 1]);
+ /// assert_eq!(iter.next().unwrap(), &[1, 2]);
+ /// assert_eq!(iter.next().unwrap(), &[2, 3]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// [`windows`]: #method.windows
+ #[unstable(feature = "array_windows", issue = "75027")]
+ #[inline]
+ pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
+ assert_ne!(N, 0);
+ ArrayWindows::new(self)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -985,7 +1016,7 @@
#[inline]
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
assert!(chunk_size != 0);
- RChunks { v: self, chunk_size }
+ RChunks::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -1023,7 +1054,7 @@
#[inline]
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
assert!(chunk_size != 0);
- RChunksMut { v: self, chunk_size }
+ RChunksMut::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -1062,9 +1093,7 @@
#[inline]
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
assert!(chunk_size != 0);
- let rem = self.len() % chunk_size;
- let (fst, snd) = self.split_at(rem);
- RChunksExact { v: snd, rem: fst, chunk_size }
+ RChunksExact::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -1107,9 +1136,7 @@
#[inline]
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
assert!(chunk_size != 0);
- let rem = self.len() % chunk_size;
- let (fst, snd) = self.split_at_mut(rem);
- RChunksExactMut { v: snd, rem: fst, chunk_size }
+ RChunksExactMut::new(self, chunk_size)
}
/// Divides one slice into two at an index.
@@ -1129,26 +1156,29 @@
///
/// {
/// let (left, right) = v.split_at(0);
- /// assert!(left == []);
- /// assert!(right == [1, 2, 3, 4, 5, 6]);
+ /// assert_eq!(left, []);
+ /// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at(2);
- /// assert!(left == [1, 2]);
- /// assert!(right == [3, 4, 5, 6]);
+ /// assert_eq!(left, [1, 2]);
+ /// assert_eq!(right, [3, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at(6);
- /// assert!(left == [1, 2, 3, 4, 5, 6]);
- /// assert!(right == []);
+ /// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ /// assert_eq!(right, []);
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
- (&self[..mid], &self[mid..])
+ assert!(mid <= self.len());
+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
+ // fulfills the requirements of `from_raw_parts_mut`.
+ unsafe { self.split_at_unchecked(mid) }
}
/// Divides one mutable slice into two at an index.
@@ -1168,26 +1198,115 @@
/// // scoped to restrict the lifetime of the borrows
/// {
/// let (left, right) = v.split_at_mut(2);
- /// assert!(left == [1, 0]);
- /// assert!(right == [3, 0, 5, 6]);
+ /// assert_eq!(left, [1, 0]);
+ /// assert_eq!(right, [3, 0, 5, 6]);
/// left[1] = 2;
/// right[1] = 4;
/// }
- /// assert!(v == [1, 2, 3, 4, 5, 6]);
+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+ assert!(mid <= self.len());
+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
+ // fulfills the requirements of `from_raw_parts_mut`.
+ unsafe { self.split_at_mut_unchecked(mid) }
+ }
+
+ /// Divides one slice into two at an index, without doing bounds checking.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// For a safe alternative see [`split_at`].
+ ///
+ /// # Safety
+ ///
+ /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+ /// even if the resulting reference is not used. The caller has to ensure that
+ /// `0 <= mid <= self.len()`.
+ ///
+ /// [`split_at`]: #method.split_at
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```compile_fail
+ /// #![feature(slice_split_at_unchecked)]
+ ///
+ /// let v = [1, 2, 3, 4, 5, 6];
+ ///
+ /// unsafe {
+ /// let (left, right) = v.split_at_unchecked(0);
+ /// assert_eq!(left, []);
+ /// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+ /// }
+ ///
+ /// unsafe {
+ /// let (left, right) = v.split_at_unchecked(2);
+ /// assert_eq!(left, [1, 2]);
+ /// assert_eq!(right, [3, 4, 5, 6]);
+ /// }
+ ///
+ /// unsafe {
+ /// let (left, right) = v.split_at_unchecked(6);
+ /// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ /// assert_eq!(right, []);
+ /// }
+ /// ```
+ #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
+ #[inline]
+ unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
+ // SAFETY: Caller has to check that `0 <= mid <= self.len()`
+ unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
+ }
+
+ /// Divides one mutable slice into two at an index, without doing bounds checking.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// For a safe alternative see [`split_at_mut`].
+ ///
+ /// # Safety
+ ///
+ /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+ /// even if the resulting reference is not used. The caller has to ensure that
+ /// `0 <= mid <= self.len()`.
+ ///
+ /// [`split_at_mut`]: #method.split_at_mut
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```compile_fail
+ /// #![feature(slice_split_at_unchecked)]
+ ///
+ /// let mut v = [1, 0, 3, 0, 5, 6];
+ /// // scoped to restrict the lifetime of the borrows
+ /// unsafe {
+ /// let (left, right) = v.split_at_mut_unchecked(2);
+ /// assert_eq!(left, [1, 0]);
+ /// assert_eq!(right, [3, 0, 5, 6]);
+ /// left[1] = 2;
+ /// right[1] = 4;
+ /// }
+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+ /// ```
+ #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
+ #[inline]
+ unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
let len = self.len();
let ptr = self.as_mut_ptr();
- // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
- // fulfills the requirements of `from_raw_parts_mut`.
- unsafe {
- assert!(mid <= len);
-
- (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid))
- }
+ // SAFETY: Caller has to check that `0 <= mid <= self.len()`.
+ //
+ // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
+ // is fine.
+ unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
}
/// Returns an iterator over subslices separated by elements that match
@@ -1236,7 +1355,7 @@
where
F: FnMut(&T) -> bool,
{
- Split { v: self, pred, finished: false }
+ Split::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@@ -1258,7 +1377,7 @@
where
F: FnMut(&T) -> bool,
{
- SplitMut { v: self, pred, finished: false }
+ SplitMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1296,7 +1415,7 @@
where
F: FnMut(&T) -> bool,
{
- SplitInclusive { v: self, pred, finished: false }
+ SplitInclusive::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@@ -1321,7 +1440,7 @@
where
F: FnMut(&T) -> bool,
{
- SplitInclusiveMut { v: self, pred, finished: false }
+ SplitInclusiveMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1357,7 +1476,7 @@
where
F: FnMut(&T) -> bool,
{
- RSplit { inner: self.split(pred) }
+ RSplit::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@@ -1383,7 +1502,7 @@
where
F: FnMut(&T) -> bool,
{
- RSplitMut { inner: self.split_mut(pred) }
+ RSplitMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1411,7 +1530,7 @@
where
F: FnMut(&T) -> bool,
{
- SplitN { inner: GenericSplitN { iter: self.split(pred), count: n } }
+ SplitN::new(self.split(pred), n)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1437,7 +1556,7 @@
where
F: FnMut(&T) -> bool,
{
- SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), count: n } }
+ SplitNMut::new(self.split_mut(pred), n)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1466,7 +1585,7 @@
where
F: FnMut(&T) -> bool,
{
- RSplitN { inner: GenericSplitN { iter: self.rsplit(pred), count: n } }
+ RSplitN::new(self.rsplit(pred), n)
}
/// Returns an iterator over subslices separated by elements that match
@@ -1493,7 +1612,7 @@
where
F: FnMut(&T) -> bool,
{
- RSplitNMut { inner: GenericSplitN { iter: self.rsplit_mut(pred), count: n } }
+ RSplitNMut::new(self.rsplit_mut(pred), n)
}
/// Returns `true` if the slice contains an element with the given value.
@@ -1515,11 +1634,12 @@
/// assert!(!v.iter().any(|e| e == "hi"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
pub fn contains(&self, x: &T) -> bool
where
T: PartialEq,
{
- x.slice_contains(self)
+ cmp::SliceContains::slice_contains(x, self)
}
/// Returns `true` if `needle` is a prefix of the slice.
@@ -2551,26 +2671,11 @@
/// ```
#[stable(feature = "copy_within", since = "1.37.0")]
#[track_caller]
- pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize)
+ pub fn copy_within<R: RangeBounds<usize>>(&mut self, src: R, dest: usize)
where
T: Copy,
{
- let src_start = match src.start_bound() {
- ops::Bound::Included(&n) => n,
- ops::Bound::Excluded(&n) => {
- n.checked_add(1).unwrap_or_else(|| slice_index_overflow_fail())
- }
- ops::Bound::Unbounded => 0,
- };
- let src_end = match src.end_bound() {
- ops::Bound::Included(&n) => {
- n.checked_add(1).unwrap_or_else(|| slice_index_overflow_fail())
- }
- ops::Bound::Excluded(&n) => n,
- ops::Bound::Unbounded => self.len(),
- };
- assert!(src_start <= src_end, "src end is before src start");
- assert!(src_end <= self.len(), "src is out of bounds");
+ let Range { start: src_start, end: src_end } = check_range(self.len(), src);
let count = src_end - src_start;
assert!(dest <= self.len() - count, "dest is out of bounds");
// SAFETY: the conditions for `ptr::copy` have all been checked above,
@@ -2958,606 +3063,6 @@
}
}
-#[lang = "slice_u8"]
-#[cfg(not(test))]
-impl [u8] {
- /// Checks if all bytes in this slice are within the ASCII range.
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn is_ascii(&self) -> bool {
- is_ascii(self)
- }
-
- /// Checks that two slices are an ASCII case-insensitive match.
- ///
- /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
- /// but without allocating and copying temporaries.
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
- self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.eq_ignore_ascii_case(b))
- }
-
- /// Converts this slice to its ASCII upper case equivalent in-place.
- ///
- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new uppercased value without modifying the existing one, use
- /// [`to_ascii_uppercase`].
- ///
- /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn make_ascii_uppercase(&mut self) {
- for byte in self {
- byte.make_ascii_uppercase();
- }
- }
-
- /// Converts this slice to its ASCII lower case equivalent in-place.
- ///
- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new lowercased value without modifying the existing one, use
- /// [`to_ascii_lowercase`].
- ///
- /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn make_ascii_lowercase(&mut self) {
- for byte in self {
- byte.make_ascii_lowercase();
- }
- }
-}
-
-/// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed
-/// from `../str/mod.rs`, which does something similar for utf8 validation.
-#[inline]
-fn contains_nonascii(v: usize) -> bool {
- const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
- (NONASCII_MASK & v) != 0
-}
-
-/// Optimized ASCII test that will use usize-at-a-time operations instead of
-/// byte-at-a-time operations (when possible).
-///
-/// The algorithm we use here is pretty simple. If `s` is too short, we just
-/// check each byte and be done with it. Otherwise:
-///
-/// - Read the first word with an unaligned load.
-/// - Align the pointer, read subsequent words until end with aligned loads.
-/// - Read the last `usize` from `s` with an unaligned load.
-///
-/// If any of these loads produces something for which `contains_nonascii`
-/// (above) returns true, then we know the answer is false.
-#[inline]
-fn is_ascii(s: &[u8]) -> bool {
- const USIZE_SIZE: usize = mem::size_of::<usize>();
-
- let len = s.len();
- let align_offset = s.as_ptr().align_offset(USIZE_SIZE);
-
- // If we wouldn't gain anything from the word-at-a-time implementation, fall
- // back to a scalar loop.
- //
- // We also do this for architectures where `size_of::<usize>()` isn't
- // sufficient alignment for `usize`, because it's a weird edge case.
- if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::<usize>() {
- return s.iter().all(|b| b.is_ascii());
- }
-
- // We always read the first word unaligned, which means `align_offset` is
- // 0, we'd read the same value again for the aligned read.
- let offset_to_aligned = if align_offset == 0 { USIZE_SIZE } else { align_offset };
-
- let start = s.as_ptr();
- // SAFETY: We verify `len < USIZE_SIZE` above.
- let first_word = unsafe { (start as *const usize).read_unaligned() };
-
- if contains_nonascii(first_word) {
- return false;
- }
- // We checked this above, somewhat implicitly. Note that `offset_to_aligned`
- // is either `align_offset` or `USIZE_SIZE`, both of are explicitly checked
- // above.
- debug_assert!(offset_to_aligned <= len);
-
- // SAFETY: word_ptr is the (properly aligned) usize ptr we use to read the
- // middle chunk of the slice.
- let mut word_ptr = unsafe { start.add(offset_to_aligned) as *const usize };
-
- // `byte_pos` is the byte index of `word_ptr`, used for loop end checks.
- let mut byte_pos = offset_to_aligned;
-
- // Paranoia check about alignment, since we're about to do a bunch of
- // unaligned loads. In practice this should be impossible barring a bug in
- // `align_offset` though.
- debug_assert_eq!((word_ptr as usize) % mem::align_of::<usize>(), 0);
-
- // Read subsequent words until the last aligned word, excluding the last
- // aligned word by itself to be done in tail check later, to ensure that
- // tail is always one `usize` at most to extra branch `byte_pos == len`.
- while byte_pos < len - USIZE_SIZE {
- debug_assert!(
- // Sanity check that the read is in bounds
- (word_ptr as usize + USIZE_SIZE) <= (start.wrapping_add(len) as usize) &&
- // And that our assumptions about `byte_pos` hold.
- (word_ptr as usize) - (start as usize) == byte_pos
- );
-
- // Safety: We know `word_ptr` is properly aligned (because of
- // `align_offset`), and we know that we have enough bytes between `word_ptr` and the end
- let word = unsafe { word_ptr.read() };
- if contains_nonascii(word) {
- return false;
- }
-
- byte_pos += USIZE_SIZE;
- // SAFETY: We know that `byte_pos <= len - USIZE_SIZE`, which means that
- // after this `add`, `word_ptr` will be at most one-past-the-end.
- word_ptr = unsafe { word_ptr.add(1) };
- }
-
- // Sanity check to ensure there really is only one `usize` left. This should
- // be guaranteed by our loop condition.
- debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE);
-
- // SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start.
- let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() };
-
- !contains_nonascii(last_word)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, I> ops::Index<I> for [T]
-where
- I: SliceIndex<[T]>,
-{
- type Output = I::Output;
-
- #[inline]
- fn index(&self, index: I) -> &I::Output {
- index.index(self)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, I> ops::IndexMut<I> for [T]
-where
- I: SliceIndex<[T]>,
-{
- #[inline]
- fn index_mut(&mut self, index: I) -> &mut I::Output {
- index.index_mut(self)
- }
-}
-
-#[inline(never)]
-#[cold]
-#[track_caller]
-fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
- panic!("range start index {} out of range for slice of length {}", index, len);
-}
-
-#[inline(never)]
-#[cold]
-#[track_caller]
-fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
- panic!("range end index {} out of range for slice of length {}", index, len);
-}
-
-#[inline(never)]
-#[cold]
-#[track_caller]
-fn slice_index_order_fail(index: usize, end: usize) -> ! {
- panic!("slice index starts at {} but ends at {}", index, end);
-}
-
-#[inline(never)]
-#[cold]
-#[track_caller]
-fn slice_index_overflow_fail() -> ! {
- panic!("attempted to index slice up to maximum usize");
-}
-
-mod private_slice_index {
- use super::ops;
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- pub trait Sealed {}
-
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for usize {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::Range<usize> {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::RangeTo<usize> {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::RangeFrom<usize> {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::RangeFull {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::RangeInclusive<usize> {}
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- impl Sealed for ops::RangeToInclusive<usize> {}
-}
-
-/// A helper trait used for indexing operations.
-///
-/// Implementations of this trait have to promise that if the argument
-/// to `get_(mut_)unchecked` is a safe reference, then so is the result.
-#[stable(feature = "slice_get_slice", since = "1.28.0")]
-#[rustc_on_unimplemented(
- on(T = "str", label = "string indices are ranges of `usize`",),
- on(
- all(any(T = "str", T = "&str", T = "std::string::String"), _Self = "{integer}"),
- note = "you can use `.chars().nth()` or `.bytes().nth()`
-see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
- ),
- message = "the type `{T}` cannot be indexed by `{Self}`",
- label = "slice indices are of type `usize` or ranges of `usize`"
-)]
-pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
- /// The output type returned by methods.
- #[stable(feature = "slice_get_slice", since = "1.28.0")]
- type Output: ?Sized;
-
- /// Returns a shared reference to the output at this location, if in
- /// bounds.
- #[unstable(feature = "slice_index_methods", issue = "none")]
- fn get(self, slice: &T) -> Option<&Self::Output>;
-
- /// Returns a mutable reference to the output at this location, if in
- /// bounds.
- #[unstable(feature = "slice_index_methods", issue = "none")]
- fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
-
- /// Returns a shared reference to the output at this location, without
- /// performing any bounds checking.
- /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
- /// is *[undefined behavior]* even if the resulting reference is not used.
- ///
- /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
- #[unstable(feature = "slice_index_methods", issue = "none")]
- unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
-
- /// Returns a mutable reference to the output at this location, without
- /// performing any bounds checking.
- /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
- /// is *[undefined behavior]* even if the resulting reference is not used.
- ///
- /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
- #[unstable(feature = "slice_index_methods", issue = "none")]
- unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
-
- /// Returns a shared reference to the output at this location, panicking
- /// if out of bounds.
- #[unstable(feature = "slice_index_methods", issue = "none")]
- #[track_caller]
- fn index(self, slice: &T) -> &Self::Output;
-
- /// Returns a mutable reference to the output at this location, panicking
- /// if out of bounds.
- #[unstable(feature = "slice_index_methods", issue = "none")]
- #[track_caller]
- fn index_mut(self, slice: &mut T) -> &mut Self::Output;
-}
-
-#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for usize {
- type Output = T;
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&T> {
- // SAFETY: `self` is checked to be in bounds.
- if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None }
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
- // SAFETY: `self` is checked to be in bounds.
- if self < slice.len() { unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } else { None }
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
- // SAFETY: the caller guarantees that `slice` is not dangling, so it
- // cannot be longer than `isize::MAX`. They also guarantee that
- // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
- // so the call to `add` is safe.
- unsafe { slice.as_ptr().add(self) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
- // SAFETY: see comments for `get_unchecked` above.
- unsafe { slice.as_mut_ptr().add(self) }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &T {
- // N.B., use intrinsic indexing
- &(*slice)[self]
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut T {
- // N.B., use intrinsic indexing
- &mut (*slice)[self]
- }
-}
-
-#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- if self.start > self.end || self.end > slice.len() {
- None
- } else {
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { Some(&*self.get_unchecked(slice)) }
- }
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- if self.start > self.end || self.end > slice.len() {
- None
- } else {
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { Some(&mut *self.get_unchecked_mut(slice)) }
- }
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- // SAFETY: the caller guarantees that `slice` is not dangling, so it
- // cannot be longer than `isize::MAX`. They also guarantee that
- // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
- // so the call to `add` is safe.
- unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- // SAFETY: see comments for `get_unchecked` above.
- unsafe {
- ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
- }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- if self.start > self.end {
- slice_index_order_fail(self.start, self.end);
- } else if self.end > slice.len() {
- slice_end_index_len_fail(self.end, slice.len());
- }
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &*self.get_unchecked(slice) }
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- if self.start > self.end {
- slice_index_order_fail(self.start, self.end);
- } else if self.end > slice.len() {
- slice_end_index_len_fail(self.end, slice.len());
- }
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &mut *self.get_unchecked_mut(slice) }
- }
-}
-
-#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- (0..self.end).get(slice)
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- (0..self.end).get_mut(slice)
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
- unsafe { (0..self.end).get_unchecked(slice) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
- unsafe { (0..self.end).get_unchecked_mut(slice) }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- (0..self.end).index(slice)
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- (0..self.end).index_mut(slice)
- }
-}
-
-#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- (self.start..slice.len()).get(slice)
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- (self.start..slice.len()).get_mut(slice)
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
- unsafe { (self.start..slice.len()).get_unchecked(slice) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
- unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- if self.start > slice.len() {
- slice_start_index_len_fail(self.start, slice.len());
- }
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &*self.get_unchecked(slice) }
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- if self.start > slice.len() {
- slice_start_index_len_fail(self.start, slice.len());
- }
- // SAFETY: `self` is checked to be valid and in bounds above.
- unsafe { &mut *self.get_unchecked_mut(slice) }
- }
-}
-
-#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- Some(slice)
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- Some(slice)
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- slice
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- slice
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- slice
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- slice
- }
-}
-
-#[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- if *self.end() == usize::MAX {
- None
- } else {
- (*self.start()..self.end() + 1).get_mut(slice)
- }
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
- unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
- unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- if *self.end() == usize::MAX {
- slice_index_overflow_fail();
- }
- (*self.start()..self.end() + 1).index(slice)
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- if *self.end() == usize::MAX {
- slice_index_overflow_fail();
- }
- (*self.start()..self.end() + 1).index_mut(slice)
- }
-}
-
-#[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
- type Output = [T];
-
- #[inline]
- fn get(self, slice: &[T]) -> Option<&[T]> {
- (0..=self.end).get(slice)
- }
-
- #[inline]
- fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
- (0..=self.end).get_mut(slice)
- }
-
- #[inline]
- unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
- unsafe { (0..=self.end).get_unchecked(slice) }
- }
-
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
- unsafe { (0..=self.end).get_unchecked_mut(slice) }
- }
-
- #[inline]
- fn index(self, slice: &[T]) -> &[T] {
- (0..=self.end).index(slice)
- }
-
- #[inline]
- fn index_mut(self, slice: &mut [T]) -> &mut [T] {
- (0..=self.end).index_mut(slice)
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Common traits
-////////////////////////////////////////////////////////////////////////////////
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for &[T] {
/// Creates an empty slice.
@@ -3573,3240 +3078,3 @@
&mut []
}
}
-
-//
-// Iterators
-//
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a [T] {
- type Item = &'a T;
- type IntoIter = Iter<'a, T>;
-
- fn into_iter(self) -> Iter<'a, T> {
- self.iter()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a mut [T] {
- type Item = &'a mut T;
- type IntoIter = IterMut<'a, T>;
-
- fn into_iter(self) -> IterMut<'a, T> {
- self.iter_mut()
- }
-}
-
-// Macro helper functions
-#[inline(always)]
-fn size_from_ptr<T>(_: *const T) -> usize {
- mem::size_of::<T>()
-}
-
-// Inlining is_empty and len makes a huge performance difference
-macro_rules! is_empty {
- // The way we encode the length of a ZST iterator, this works both for ZST
- // and non-ZST.
- ($self: ident) => {
- $self.ptr.as_ptr() as *const T == $self.end
- };
-}
-
-// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
-// unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
-macro_rules! len {
- ($self: ident) => {{
- #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
-
- let start = $self.ptr;
- let size = size_from_ptr(start.as_ptr());
- if size == 0 {
- // This _cannot_ use `unchecked_sub` because we depend on wrapping
- // to represent the length of long ZST slice iterators.
- ($self.end as usize).wrapping_sub(start.as_ptr() as usize)
- } else {
- // We know that `start <= end`, so can do better than `offset_from`,
- // which needs to deal in signed. By setting appropriate flags here
- // we can tell LLVM this, which helps it remove bounds checks.
- // SAFETY: By the type invariant, `start <= end`
- let diff = unsafe { unchecked_sub($self.end as usize, start.as_ptr() as usize) };
- // By also telling LLVM that the pointers are apart by an exact
- // multiple of the type size, it can optimize `len() == 0` down to
- // `start == end` instead of `(end - start) < size`.
- // SAFETY: By the type invariant, the pointers are aligned so the
- // distance between them must be a multiple of pointee size
- unsafe { exact_div(diff, size) }
- }
- }};
-}
-
-// The shared definition of the `Iter` and `IterMut` iterators
-macro_rules! iterator {
- (
- struct $name:ident -> $ptr:ty,
- $elem:ty,
- $raw_mut:tt,
- {$( $mut_:tt )?},
- {$($extra:tt)*}
- ) => {
- // Returns the first element and moves the start of the iterator forwards by 1.
- // Greatly improves performance compared to an inlined function. The iterator
- // must not be empty.
- macro_rules! next_unchecked {
- ($self: ident) => {& $( $mut_ )? *$self.post_inc_start(1)}
- }
-
- // Returns the last element and moves the end of the iterator backwards by 1.
- // Greatly improves performance compared to an inlined function. The iterator
- // must not be empty.
- macro_rules! next_back_unchecked {
- ($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)}
- }
-
- // Shrinks the iterator when T is a ZST, by moving the end of the iterator
- // backwards by `n`. `n` must not exceed `self.len()`.
- macro_rules! zst_shrink {
- ($self: ident, $n: ident) => {
- $self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
- }
- }
-
- impl<'a, T> $name<'a, T> {
- // Helper function for creating a slice from the iterator.
- #[inline(always)]
- fn make_slice(&self) -> &'a [T] {
- // SAFETY: the iterator was created from a slice with pointer
- // `self.ptr` and length `len!(self)`. This guarantees that all
- // the prerequisites for `from_raw_parts` are fulfilled.
- unsafe { from_raw_parts(self.ptr.as_ptr(), len!(self)) }
- }
-
- // Helper function for moving the start of the iterator forwards by `offset` elements,
- // returning the old start.
- // Unsafe because the offset must not exceed `self.len()`.
- #[inline(always)]
- unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
- if mem::size_of::<T>() == 0 {
- zst_shrink!(self, offset);
- self.ptr.as_ptr()
- } else {
- let old = self.ptr.as_ptr();
- // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
- // so this new pointer is inside `self` and thus guaranteed to be non-null.
- self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
- old
- }
- }
-
- // Helper function for moving the end of the iterator backwards by `offset` elements,
- // returning the new end.
- // Unsafe because the offset must not exceed `self.len()`.
- #[inline(always)]
- unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
- if mem::size_of::<T>() == 0 {
- zst_shrink!(self, offset);
- self.ptr.as_ptr()
- } else {
- // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
- // which is guaranteed to not overflow an `isize`. Also, the resulting pointer
- // is in bounds of `slice`, which fulfills the other requirements for `offset`.
- self.end = unsafe { self.end.offset(-offset) };
- self.end
- }
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<T> ExactSizeIterator for $name<'_, T> {
- #[inline(always)]
- fn len(&self) -> usize {
- len!(self)
- }
-
- #[inline(always)]
- fn is_empty(&self) -> bool {
- is_empty!(self)
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<'a, T> Iterator for $name<'a, T> {
- type Item = $elem;
-
- #[inline]
- fn next(&mut self) -> Option<$elem> {
- // could be implemented with slices, but this avoids bounds checks
-
- // SAFETY: `assume` calls are safe since a slice's start pointer
- // must be non-null, and slices over non-ZSTs must also have a
- // non-null end pointer. The call to `next_unchecked!` is safe
- // since we check if the iterator is empty first.
- unsafe {
- assume(!self.ptr.as_ptr().is_null());
- if mem::size_of::<T>() != 0 {
- assume(!self.end.is_null());
- }
- if is_empty!(self) {
- None
- } else {
- Some(next_unchecked!(self))
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let exact = len!(self);
- (exact, Some(exact))
- }
-
- #[inline]
- fn count(self) -> usize {
- len!(self)
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<$elem> {
- if n >= len!(self) {
- // This iterator is now empty.
- if mem::size_of::<T>() == 0 {
- // We have to do it this way as `ptr` may never be 0, but `end`
- // could be (due to wrapping).
- self.end = self.ptr.as_ptr();
- } else {
- // SAFETY: end can't be 0 if T isn't ZST because ptr isn't 0 and end >= ptr
- unsafe {
- self.ptr = NonNull::new_unchecked(self.end as *mut T);
- }
- }
- return None;
- }
- // SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
- unsafe {
- self.post_inc_start(n as isize);
- Some(next_unchecked!(self))
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<$elem> {
- self.next_back()
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile.
- #[inline]
- fn for_each<F>(mut self, mut f: F)
- where
- Self: Sized,
- F: FnMut(Self::Item),
- {
- while let Some(x) = self.next() {
- f(x);
- }
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile.
- #[inline]
- fn all<F>(&mut self, mut f: F) -> bool
- where
- Self: Sized,
- F: FnMut(Self::Item) -> bool,
- {
- while let Some(x) = self.next() {
- if !f(x) {
- return false;
- }
- }
- true
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile.
- #[inline]
- fn any<F>(&mut self, mut f: F) -> bool
- where
- Self: Sized,
- F: FnMut(Self::Item) -> bool,
- {
- while let Some(x) = self.next() {
- if f(x) {
- return true;
- }
- }
- false
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile.
- #[inline]
- fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
- where
- Self: Sized,
- P: FnMut(&Self::Item) -> bool,
- {
- while let Some(x) = self.next() {
- if predicate(&x) {
- return Some(x);
- }
- }
- None
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile.
- #[inline]
- fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
- where
- Self: Sized,
- F: FnMut(Self::Item) -> Option<B>,
- {
- while let Some(x) = self.next() {
- if let Some(y) = f(x) {
- return Some(y);
- }
- }
- None
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile. Also, the `assume` avoids a bounds check.
- #[inline]
- #[rustc_inherit_overflow_checks]
- fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
- Self: Sized,
- P: FnMut(Self::Item) -> bool,
- {
- let n = len!(self);
- let mut i = 0;
- while let Some(x) = self.next() {
- if predicate(x) {
- // SAFETY: we are guaranteed to be in bounds by the loop invariant:
- // when `i >= n`, `self.next()` returns `None` and the loop breaks.
- unsafe { assume(i < n) };
- return Some(i);
- }
- i += 1;
- }
- None
- }
-
- // We override the default implementation, which uses `try_fold`,
- // because this simple implementation generates less LLVM IR and is
- // faster to compile. Also, the `assume` avoids a bounds check.
- #[inline]
- fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
- P: FnMut(Self::Item) -> bool,
- Self: Sized + ExactSizeIterator + DoubleEndedIterator
- {
- let n = len!(self);
- let mut i = n;
- while let Some(x) = self.next_back() {
- i -= 1;
- if predicate(x) {
- // SAFETY: `i` must be lower than `n` since it starts at `n`
- // and is only decreasing.
- unsafe { assume(i < n) };
- return Some(i);
- }
- }
- None
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- // SAFETY: the caller must guarantee that `i` is in bounds of
- // the underlying slice, so `i` cannot overflow an `isize`, and
- // the returned references is guaranteed to refer to an element
- // of the slice and thus guaranteed to be valid.
- //
- // Also note that the caller also guarantees that we're never
- // called with the same index again, and that no other methods
- // that will access this subslice are called, so it is valid
- // for the returned reference to be mutable in the case of
- // `IterMut`
- unsafe { & $( $mut_ )? * self.ptr.as_ptr().add(idx) }
- }
-
- $($extra)*
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<'a, T> DoubleEndedIterator for $name<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<$elem> {
- // could be implemented with slices, but this avoids bounds checks
-
- // SAFETY: `assume` calls are safe since a slice's start pointer must be non-null,
- // and slices over non-ZSTs must also have a non-null end pointer.
- // The call to `next_back_unchecked!` is safe since we check if the iterator is
- // empty first.
- unsafe {
- assume(!self.ptr.as_ptr().is_null());
- if mem::size_of::<T>() != 0 {
- assume(!self.end.is_null());
- }
- if is_empty!(self) {
- None
- } else {
- Some(next_back_unchecked!(self))
- }
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<$elem> {
- if n >= len!(self) {
- // This iterator is now empty.
- self.end = self.ptr.as_ptr();
- return None;
- }
- // SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
- unsafe {
- self.pre_dec_end(n as isize);
- Some(next_back_unchecked!(self))
- }
- }
- }
-
- #[stable(feature = "fused", since = "1.26.0")]
- impl<T> FusedIterator for $name<'_, T> {}
-
- #[unstable(feature = "trusted_len", issue = "37572")]
- unsafe impl<T> TrustedLen for $name<'_, T> {}
- }
-}
-
-/// Immutable slice iterator
-///
-/// This struct is created by the [`iter`] method on [slices].
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]):
-/// let slice = &[1, 2, 3];
-///
-/// // Then, we iterate over it:
-/// for element in slice.iter() {
-/// println!("{}", element);
-/// }
-/// ```
-///
-/// [`iter`]: ../../std/primitive.slice.html#method.iter
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, T: 'a> {
- ptr: NonNull<T>,
- end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
- // ptr == end is a quick test for the Iterator being empty, that works
- // for both ZST and non-ZST.
- _marker: marker::PhantomData<&'a T>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("Iter").field(&self.as_slice()).finish()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for Iter<'_, T> {}
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Send for Iter<'_, T> {}
-
-impl<'a, T> Iter<'a, T> {
- /// Views the underlying data as a subslice of the original data.
- ///
- /// This has the same lifetime as the original slice, and so the
- /// iterator can continue to be used while this exists.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// // First, we declare a type which has the `iter` method to get the `Iter`
- /// // struct (&[usize here]):
- /// let slice = &[1, 2, 3];
- ///
- /// // Then, we get the iterator:
- /// let mut iter = slice.iter();
- /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]":
- /// println!("{:?}", iter.as_slice());
- ///
- /// // Next, we move to the second element of the slice:
- /// iter.next();
- /// // Now `as_slice` returns "[2, 3]":
- /// println!("{:?}", iter.as_slice());
- /// ```
- #[stable(feature = "iter_to_slice", since = "1.4.0")]
- pub fn as_slice(&self) -> &'a [T] {
- self.make_slice()
- }
-}
-
-iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, {
- fn is_sorted_by<F>(self, mut compare: F) -> bool
- where
- Self: Sized,
- F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
- {
- self.as_slice().windows(2).all(|w| {
- compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false)
- })
- }
-}}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Clone for Iter<'_, T> {
- fn clone(&self) -> Self {
- Iter { ptr: self.ptr, end: self.end, _marker: self._marker }
- }
-}
-
-#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
-impl<T> AsRef<[T]> for Iter<'_, T> {
- fn as_ref(&self) -> &[T] {
- self.as_slice()
- }
-}
-
-/// Mutable slice iterator.
-///
-/// This struct is created by the [`iter_mut`] method on [slices].
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
-/// // struct (&[usize here]):
-/// let mut slice = &mut [1, 2, 3];
-///
-/// // Then, we iterate over it and increment each element value:
-/// for element in slice.iter_mut() {
-/// *element += 1;
-/// }
-///
-/// // We now have "[2, 3, 4]":
-/// println!("{:?}", slice);
-/// ```
-///
-/// [`iter_mut`]: ../../std/primitive.slice.html#method.iter_mut
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IterMut<'a, T: 'a> {
- ptr: NonNull<T>,
- end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
- // ptr == end is a quick test for the Iterator being empty, that works
- // for both ZST and non-ZST.
- _marker: marker::PhantomData<&'a mut T>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("IterMut").field(&self.make_slice()).finish()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Send> Send for IterMut<'_, T> {}
-
-impl<'a, T> IterMut<'a, T> {
- /// Views the underlying data as a subslice of the original data.
- ///
- /// To avoid creating `&mut` references that alias, this is forced
- /// to consume the iterator.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// // First, we declare a type which has `iter_mut` method to get the `IterMut`
- /// // struct (&[usize here]):
- /// let mut slice = &mut [1, 2, 3];
- ///
- /// {
- /// // Then, we get the iterator:
- /// let mut iter = slice.iter_mut();
- /// // We move to next element:
- /// iter.next();
- /// // So if we print what `into_slice` method returns here, we have "[2, 3]":
- /// println!("{:?}", iter.into_slice());
- /// }
- ///
- /// // Now let's modify a value of the slice:
- /// {
- /// // First we get back the iterator:
- /// let mut iter = slice.iter_mut();
- /// // We change the value of the first element of the slice returned by the `next` method:
- /// *iter.next().unwrap() += 1;
- /// }
- /// // Now slice is "[2, 2, 3]":
- /// println!("{:?}", slice);
- /// ```
- #[stable(feature = "iter_to_slice", since = "1.4.0")]
- pub fn into_slice(self) -> &'a mut [T] {
- // SAFETY: the iterator was created from a mutable slice with pointer
- // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
- // for `from_raw_parts_mut` are fulfilled.
- unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
- }
-
- /// Views the underlying data as a subslice of the original data.
- ///
- /// To avoid creating `&mut [T]` references that alias, the returned slice
- /// borrows its lifetime from the iterator the method is applied on.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// # #![feature(slice_iter_mut_as_slice)]
- /// let mut slice: &mut [usize] = &mut [1, 2, 3];
- ///
- /// // First, we get the iterator:
- /// let mut iter = slice.iter_mut();
- /// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]":
- /// assert_eq!(iter.as_slice(), &[1, 2, 3]);
- ///
- /// // Next, we move to the second element of the slice:
- /// iter.next();
- /// // Now `as_slice` returns "[2, 3]":
- /// assert_eq!(iter.as_slice(), &[2, 3]);
- /// ```
- #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")]
- pub fn as_slice(&self) -> &[T] {
- self.make_slice()
- }
-}
-
-iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
-
-/// An internal abstraction over the splitting iterators, so that
-/// splitn, splitn_mut etc can be implemented once.
-#[doc(hidden)]
-trait SplitIter: DoubleEndedIterator {
- /// Marks the underlying iterator as complete, extracting the remaining
- /// portion of the slice.
- fn finish(&mut self) -> Option<Self::Item>;
-}
-
-/// An iterator over subslices separated by elements that match a predicate
-/// function.
-///
-/// This struct is created by the [`split`] method on [slices].
-///
-/// [`split`]: ../../std/primitive.slice.html#method.split
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Split<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- v: &'a [T],
- pred: P,
- finished: bool,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish()
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, P> Clone for Split<'_, T, P>
-where
- P: Clone + FnMut(&T) -> bool,
-{
- fn clone(&self) -> Self {
- Split { v: self.v, pred: self.pred.clone(), finished: self.finished }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, P> Iterator for Split<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.finished {
- return None;
- }
-
- match self.v.iter().position(|x| (self.pred)(x)) {
- None => self.finish(),
- Some(idx) => {
- let ret = Some(&self.v[..idx]);
- self.v = &self.v[idx + 1..];
- ret
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.finished {
- return None;
- }
-
- match self.v.iter().rposition(|x| (self.pred)(x)) {
- None => self.finish(),
- Some(idx) => {
- let ret = Some(&self.v[idx + 1..]);
- self.v = &self.v[..idx];
- ret
- }
- }
- }
-}
-
-impl<'a, T, P> SplitIter for Split<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn finish(&mut self) -> Option<&'a [T]> {
- if self.finished {
- None
- } else {
- self.finished = true;
- Some(self.v)
- }
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An iterator over subslices separated by elements that match a predicate
-/// function. Unlike `Split`, it contains the matched part as a terminator
-/// of the subslice.
-///
-/// This struct is created by the [`split_inclusive`] method on [slices].
-///
-/// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
-/// [slices]: ../../std/primitive.slice.html
-#[unstable(feature = "split_inclusive", issue = "72360")]
-pub struct SplitInclusive<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- v: &'a [T],
- pred: P,
- finished: bool,
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitInclusive")
- .field("v", &self.v)
- .field("finished", &self.finished)
- .finish()
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<T, P> Clone for SplitInclusive<'_, T, P>
-where
- P: Clone + FnMut(&T) -> bool,
-{
- fn clone(&self) -> Self {
- SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.finished {
- return None;
- }
-
- let idx =
- self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
- if idx == self.v.len() {
- self.finished = true;
- }
- let ret = Some(&self.v[..idx]);
- self.v = &self.v[idx..];
- ret
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.finished {
- return None;
- }
-
- // The last index of self.v is already checked and found to match
- // by the last iteration, so we start searching a new match
- // one index to the left.
- let remainder = if self.v.is_empty() { &[] } else { &self.v[..(self.v.len() - 1)] };
- let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
- if idx == 0 {
- self.finished = true;
- }
- let ret = Some(&self.v[idx..]);
- self.v = &self.v[..idx];
- ret
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An iterator over the mutable subslices of the vector which are separated
-/// by elements that match `pred`.
-///
-/// This struct is created by the [`split_mut`] method on [slices].
-///
-/// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SplitMut<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- v: &'a mut [T],
- pred: P,
- finished: bool,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish()
- }
-}
-
-impl<'a, T, P> SplitIter for SplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn finish(&mut self) -> Option<&'a mut [T]> {
- if self.finished {
- None
- } else {
- self.finished = true;
- Some(mem::replace(&mut self.v, &mut []))
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, P> Iterator for SplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.finished {
- return None;
- }
-
- let idx_opt = {
- // work around borrowck limitations
- let pred = &mut self.pred;
- self.v.iter().position(|x| (*pred)(x))
- };
- match idx_opt {
- None => self.finish(),
- Some(idx) => {
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(idx);
- self.v = &mut tail[1..];
- Some(head)
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.finished {
- (0, Some(0))
- } else {
- // if the predicate doesn't match anything, we yield one slice
- // if it matches every element, we yield len+1 empty slices.
- (1, Some(self.v.len() + 1))
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.finished {
- return None;
- }
-
- let idx_opt = {
- // work around borrowck limitations
- let pred = &mut self.pred;
- self.v.iter().rposition(|x| (*pred)(x))
- };
- match idx_opt {
- None => self.finish(),
- Some(idx) => {
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(idx);
- self.v = head;
- Some(&mut tail[1..])
- }
- }
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An iterator over the mutable subslices of the vector which are separated
-/// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
-/// parts in the ends of the subslices.
-///
-/// This struct is created by the [`split_inclusive_mut`] method on [slices].
-///
-/// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
-/// [slices]: ../../std/primitive.slice.html
-#[unstable(feature = "split_inclusive", issue = "72360")]
-pub struct SplitInclusiveMut<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- v: &'a mut [T],
- pred: P,
- finished: bool,
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitInclusiveMut")
- .field("v", &self.v)
- .field("finished", &self.finished)
- .finish()
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.finished {
- return None;
- }
-
- let idx_opt = {
- // work around borrowck limitations
- let pred = &mut self.pred;
- self.v.iter().position(|x| (*pred)(x))
- };
- let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
- if idx == self.v.len() {
- self.finished = true;
- }
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(idx);
- self.v = tail;
- Some(head)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.finished {
- (0, Some(0))
- } else {
- // if the predicate doesn't match anything, we yield one slice
- // if it matches every element, we yield len+1 empty slices.
- (1, Some(self.v.len() + 1))
- }
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.finished {
- return None;
- }
-
- let idx_opt = if self.v.is_empty() {
- None
- } else {
- // work around borrowck limitations
- let pred = &mut self.pred;
-
- // The last index of self.v is already checked and found to match
- // by the last iteration, so we start searching a new match
- // one index to the left.
- let remainder = &self.v[..(self.v.len() - 1)];
- remainder.iter().rposition(|x| (*pred)(x))
- };
- let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
- if idx == 0 {
- self.finished = true;
- }
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(idx);
- self.v = head;
- Some(tail)
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An iterator over subslices separated by elements that match a predicate
-/// function, starting from the end of the slice.
-///
-/// This struct is created by the [`rsplit`] method on [slices].
-///
-/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
-pub struct RSplit<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: Split<'a, T, P>,
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("RSplit")
- .field("v", &self.inner.v)
- .field("finished", &self.inner.finished)
- .finish()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> Iterator for RSplit<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- self.inner.next_back()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- self.inner.next()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> SplitIter for RSplit<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn finish(&mut self) -> Option<&'a [T]> {
- self.inner.finish()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An iterator over the subslices of the vector which are separated
-/// by elements that match `pred`, starting from the end of the slice.
-///
-/// This struct is created by the [`rsplit_mut`] method on [slices].
-///
-/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-pub struct RSplitMut<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: SplitMut<'a, T, P>,
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("RSplitMut")
- .field("v", &self.inner.v)
- .field("finished", &self.inner.finished)
- .finish()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> SplitIter for RSplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn finish(&mut self) -> Option<&'a mut [T]> {
- self.inner.finish()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> Iterator for RSplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- self.inner.next_back()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- self.inner.next()
- }
-}
-
-#[stable(feature = "slice_rsplit", since = "1.27.0")]
-impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
-
-/// An private iterator over subslices separated by elements that
-/// match a predicate function, splitting at most a fixed number of
-/// times.
-#[derive(Debug)]
-struct GenericSplitN<I> {
- iter: I,
- count: usize,
-}
-
-impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
- type Item = T;
-
- #[inline]
- fn next(&mut self) -> Option<T> {
- match self.count {
- 0 => None,
- 1 => {
- self.count -= 1;
- self.iter.finish()
- }
- _ => {
- self.count -= 1;
- self.iter.next()
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (lower, upper_opt) = self.iter.size_hint();
- (lower, upper_opt.map(|upper| cmp::min(self.count, upper)))
- }
-}
-
-/// An iterator over subslices separated by elements that match a predicate
-/// function, limited to a given number of splits.
-///
-/// This struct is created by the [`splitn`] method on [slices].
-///
-/// [`splitn`]: ../../std/primitive.slice.html#method.splitn
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SplitN<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: GenericSplitN<Split<'a, T, P>>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitN").field("inner", &self.inner).finish()
- }
-}
-
-/// An iterator over subslices separated by elements that match a
-/// predicate function, limited to a given number of splits, starting
-/// from the end of the slice.
-///
-/// This struct is created by the [`rsplitn`] method on [slices].
-///
-/// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct RSplitN<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: GenericSplitN<RSplit<'a, T, P>>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("RSplitN").field("inner", &self.inner).finish()
- }
-}
-
-/// An iterator over subslices separated by elements that match a predicate
-/// function, limited to a given number of splits.
-///
-/// This struct is created by the [`splitn_mut`] method on [slices].
-///
-/// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SplitNMut<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: GenericSplitN<SplitMut<'a, T, P>>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitNMut").field("inner", &self.inner).finish()
- }
-}
-
-/// An iterator over subslices separated by elements that match a
-/// predicate function, limited to a given number of splits, starting
-/// from the end of the slice.
-///
-/// This struct is created by the [`rsplitn_mut`] method on [slices].
-///
-/// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut
-/// [slices]: ../../std/primitive.slice.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct RSplitNMut<'a, T: 'a, P>
-where
- P: FnMut(&T) -> bool,
-{
- inner: GenericSplitN<RSplitMut<'a, T, P>>,
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P>
-where
- P: FnMut(&T) -> bool,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("RSplitNMut").field("inner", &self.inner).finish()
- }
-}
-
-macro_rules! forward_iterator {
- ($name:ident: $elem:ident, $iter_of:ty) => {
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<'a, $elem, P> Iterator for $name<'a, $elem, P>
- where
- P: FnMut(&T) -> bool,
- {
- type Item = $iter_of;
-
- #[inline]
- fn next(&mut self) -> Option<$iter_of> {
- self.inner.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
- }
-
- #[stable(feature = "fused", since = "1.26.0")]
- impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P> where P: FnMut(&T) -> bool {}
- };
-}
-
-forward_iterator! { SplitN: T, &'a [T] }
-forward_iterator! { RSplitN: T, &'a [T] }
-forward_iterator! { SplitNMut: T, &'a mut [T] }
-forward_iterator! { RSplitNMut: T, &'a mut [T] }
-
-/// An iterator over overlapping subslices of length `size`.
-///
-/// This struct is created by the [`windows`] method on [slices].
-///
-/// [`windows`]: ../../std/primitive.slice.html#method.windows
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Windows<'a, T: 'a> {
- v: &'a [T],
- size: usize,
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Clone for Windows<'_, T> {
- fn clone(&self) -> Self {
- Windows { v: self.v, size: self.size }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Iterator for Windows<'a, T> {
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.size > self.v.len() {
- None
- } else {
- let ret = Some(&self.v[..self.size]);
- self.v = &self.v[1..];
- ret
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.size > self.v.len() {
- (0, Some(0))
- } else {
- let size = self.v.len() - self.size + 1;
- (size, Some(size))
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- let (end, overflow) = self.size.overflowing_add(n);
- if end > self.v.len() || overflow {
- self.v = &[];
- None
- } else {
- let nth = &self.v[n..end];
- self.v = &self.v[n + 1..];
- Some(nth)
- }
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- if self.size > self.v.len() {
- None
- } else {
- let start = self.v.len() - self.size;
- Some(&self.v[start..])
- }
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- // SAFETY: since the caller guarantees that `i` is in bounds,
- // which means that `i` cannot overflow an `isize`, and the
- // slice created by `from_raw_parts` is a subslice of `self.v`
- // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
- unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.size > self.v.len() {
- None
- } else {
- let ret = Some(&self.v[self.v.len() - self.size..]);
- self.v = &self.v[..self.v.len() - 1];
- ret
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let (end, overflow) = self.v.len().overflowing_sub(n);
- if end < self.size || overflow {
- self.v = &[];
- None
- } else {
- let ret = &self.v[end - self.size..end];
- self.v = &self.v[..end - 1];
- Some(ret)
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for Windows<'_, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for Windows<'_, T> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Windows<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
-/// time), starting at the beginning of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last slice
-/// of the iteration will be the remainder.
-///
-/// This struct is created by the [`chunks`] method on [slices].
-///
-/// [`chunks`]: ../../std/primitive.slice.html#method.chunks
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Chunks<'a, T: 'a> {
- v: &'a [T],
- chunk_size: usize,
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Clone for Chunks<'_, T> {
- fn clone(&self) -> Self {
- Chunks { v: self.v, chunk_size: self.chunk_size }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Iterator for Chunks<'a, T> {
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.v.is_empty() {
- None
- } else {
- let chunksz = cmp::min(self.v.len(), self.chunk_size);
- let (fst, snd) = self.v.split_at(chunksz);
- self.v = snd;
- Some(fst)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.v.is_empty() {
- (0, Some(0))
- } else {
- let n = self.v.len() / self.chunk_size;
- let rem = self.v.len() % self.chunk_size;
- let n = if rem > 0 { n + 1 } else { n };
- (n, Some(n))
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- let (start, overflow) = n.overflowing_mul(self.chunk_size);
- if start >= self.v.len() || overflow {
- self.v = &[];
- None
- } else {
- let end = match start.checked_add(self.chunk_size) {
- Some(sum) => cmp::min(self.v.len(), sum),
- None => self.v.len(),
- };
- let nth = &self.v[start..end];
- self.v = &self.v[end..];
- Some(nth)
- }
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- if self.v.is_empty() {
- None
- } else {
- let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
- Some(&self.v[start..])
- }
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let start = idx * self.chunk_size;
- let end = match start.checked_add(self.chunk_size) {
- None => self.v.len(),
- Some(end) => cmp::min(end, self.v.len()),
- };
- // SAFETY: the caller guarantees that `i` is in bounds,
- // which means that `start` must be in bounds of the
- // underlying `self.v` slice, and we made sure that `end`
- // is also in bounds of `self.v`. Thus, `start` cannot overflow
- // an `isize`, and the slice constructed by `from_raw_parts`
- // is a subslice of `self.v` which is guaranteed to be valid
- // for the lifetime `'a` of `self.v`.
- unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.v.is_empty() {
- None
- } else {
- let remainder = self.v.len() % self.chunk_size;
- let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
- let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
- self.v = fst;
- Some(snd)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &[];
- None
- } else {
- let start = (len - 1 - n) * self.chunk_size;
- let end = match start.checked_add(self.chunk_size) {
- Some(res) => cmp::min(res, self.v.len()),
- None => self.v.len(),
- };
- let nth_back = &self.v[start..end];
- self.v = &self.v[..start];
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for Chunks<'_, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for Chunks<'_, T> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Chunks<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
-/// elements at a time), starting at the beginning of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last slice
-/// of the iteration will be the remainder.
-///
-/// This struct is created by the [`chunks_mut`] method on [slices].
-///
-/// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ChunksMut<'a, T: 'a> {
- v: &'a mut [T],
- chunk_size: usize,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Iterator for ChunksMut<'a, T> {
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.v.is_empty() {
- None
- } else {
- let sz = cmp::min(self.v.len(), self.chunk_size);
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(sz);
- self.v = tail;
- Some(head)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.v.is_empty() {
- (0, Some(0))
- } else {
- let n = self.v.len() / self.chunk_size;
- let rem = self.v.len() % self.chunk_size;
- let n = if rem > 0 { n + 1 } else { n };
- (n, Some(n))
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
- let (start, overflow) = n.overflowing_mul(self.chunk_size);
- if start >= self.v.len() || overflow {
- self.v = &mut [];
- None
- } else {
- let end = match start.checked_add(self.chunk_size) {
- Some(sum) => cmp::min(self.v.len(), sum),
- None => self.v.len(),
- };
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(end);
- let (_, nth) = head.split_at_mut(start);
- self.v = tail;
- Some(nth)
- }
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- if self.v.is_empty() {
- None
- } else {
- let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
- Some(&mut self.v[start..])
- }
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let start = idx * self.chunk_size;
- let end = match start.checked_add(self.chunk_size) {
- None => self.v.len(),
- Some(end) => cmp::min(end, self.v.len()),
- };
- // SAFETY: see comments for `Chunks::get_unchecked`.
- //
- // Also note that the caller also guarantees that we're never called
- // with the same index again, and that no other methods that will
- // access this subslice are called, so it is valid for the returned
- // slice to be mutable.
- unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.v.is_empty() {
- None
- } else {
- let remainder = self.v.len() % self.chunk_size;
- let sz = if remainder != 0 { remainder } else { self.chunk_size };
- let tmp = mem::replace(&mut self.v, &mut []);
- let tmp_len = tmp.len();
- let (head, tail) = tmp.split_at_mut(tmp_len - sz);
- self.v = head;
- Some(tail)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &mut [];
- None
- } else {
- let start = (len - 1 - n) * self.chunk_size;
- let end = match start.checked_add(self.chunk_size) {
- Some(res) => cmp::min(res, self.v.len()),
- None => self.v.len(),
- };
- let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
- let (head, nth_back) = temp.split_at_mut(start);
- self.v = head;
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for ChunksMut<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
-/// time), starting at the beginning of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last
-/// up to `chunk_size-1` elements will be omitted but can be retrieved from
-/// the [`remainder`] function from the iterator.
-///
-/// This struct is created by the [`chunks_exact`] method on [slices].
-///
-/// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact
-/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-pub struct ChunksExact<'a, T: 'a> {
- v: &'a [T],
- rem: &'a [T],
- chunk_size: usize,
-}
-
-impl<'a, T> ChunksExact<'a, T> {
- /// Returns the remainder of the original slice that is not going to be
- /// returned by the iterator. The returned slice has at most `chunk_size-1`
- /// elements.
- #[stable(feature = "chunks_exact", since = "1.31.0")]
- pub fn remainder(&self) -> &'a [T] {
- self.rem
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<T> Clone for ChunksExact<'_, T> {
- fn clone(&self) -> Self {
- ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<'a, T> Iterator for ChunksExact<'a, T> {
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let (fst, snd) = self.v.split_at(self.chunk_size);
- self.v = snd;
- Some(fst)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let n = self.v.len() / self.chunk_size;
- (n, Some(n))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- let (start, overflow) = n.overflowing_mul(self.chunk_size);
- if start >= self.v.len() || overflow {
- self.v = &[];
- None
- } else {
- let (_, snd) = self.v.split_at(start);
- self.v = snd;
- self.next()
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<Self::Item> {
- self.next_back()
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let start = idx * self.chunk_size;
- // SAFETY: mostly identical to `Chunks::get_unchecked`.
- unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
- self.v = fst;
- Some(snd)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &[];
- None
- } else {
- let start = (len - 1 - n) * self.chunk_size;
- let end = start + self.chunk_size;
- let nth_back = &self.v[start..end];
- self.v = &self.v[..start];
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<T> ExactSizeIterator for ChunksExact<'_, T> {
- fn is_empty(&self) -> bool {
- self.v.is_empty()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<T> FusedIterator for ChunksExact<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
-/// elements at a time), starting at the beginning of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last up to
-/// `chunk_size-1` elements will be omitted but can be retrieved from the
-/// [`into_remainder`] function from the iterator.
-///
-/// This struct is created by the [`chunks_exact_mut`] method on [slices].
-///
-/// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut
-/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-pub struct ChunksExactMut<'a, T: 'a> {
- v: &'a mut [T],
- rem: &'a mut [T],
- chunk_size: usize,
-}
-
-impl<'a, T> ChunksExactMut<'a, T> {
- /// Returns the remainder of the original slice that is not going to be
- /// returned by the iterator. The returned slice has at most `chunk_size-1`
- /// elements.
- #[stable(feature = "chunks_exact", since = "1.31.0")]
- pub fn into_remainder(self) -> &'a mut [T] {
- self.rem
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<'a, T> Iterator for ChunksExactMut<'a, T> {
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(self.chunk_size);
- self.v = tail;
- Some(head)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let n = self.v.len() / self.chunk_size;
- (n, Some(n))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
- let (start, overflow) = n.overflowing_mul(self.chunk_size);
- if start >= self.v.len() || overflow {
- self.v = &mut [];
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let (_, snd) = tmp.split_at_mut(start);
- self.v = snd;
- self.next()
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<Self::Item> {
- self.next_back()
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let start = idx * self.chunk_size;
- // SAFETY: see comments for `ChunksMut::get_unchecked`.
- unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let tmp_len = tmp.len();
- let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
- self.v = head;
- Some(tail)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &mut [];
- None
- } else {
- let start = (len - 1 - n) * self.chunk_size;
- let end = start + self.chunk_size;
- let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
- let (head, nth_back) = temp.split_at_mut(start);
- self.v = head;
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
- fn is_empty(&self) -> bool {
- self.v.is_empty()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
-
-#[stable(feature = "chunks_exact", since = "1.31.0")]
-impl<T> FusedIterator for ChunksExactMut<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) chunks (`N` elements at a
-/// time), starting at the beginning of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last
-/// up to `chunk_size-1` elements will be omitted but can be retrieved from
-/// the [`remainder`] function from the iterator.
-///
-/// This struct is created by the [`array_chunks`] method on [slices].
-///
-/// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
-/// [`remainder`]: ../../std/slice/struct.ArrayChunks.html#method.remainder
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[unstable(feature = "array_chunks", issue = "74985")]
-pub struct ArrayChunks<'a, T: 'a, const N: usize> {
- iter: Iter<'a, [T; N]>,
- rem: &'a [T],
-}
-
-impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
- /// Returns the remainder of the original slice that is not going to be
- /// returned by the iterator. The returned slice has at most `chunk_size-1`
- /// elements.
- #[unstable(feature = "array_chunks", issue = "74985")]
- pub fn remainder(&self) -> &'a [T] {
- self.rem
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[unstable(feature = "array_chunks", issue = "74985")]
-impl<T, const N: usize> Clone for ArrayChunks<'_, T, N> {
- fn clone(&self) -> Self {
- ArrayChunks { iter: self.iter.clone(), rem: self.rem }
- }
-}
-
-#[unstable(feature = "array_chunks", issue = "74985")]
-impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
- type Item = &'a [T; N];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T; N]> {
- self.iter.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- #[inline]
- fn count(self) -> usize {
- self.iter.count()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- self.iter.nth(n)
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- self.iter.last()
- }
-
- unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
- // SAFETY: The safety guarantees of `get_unchecked` are transferred to
- // the caller.
- unsafe { self.iter.__iterator_get_unchecked(i) }
- }
-}
-
-#[unstable(feature = "array_chunks", issue = "74985")]
-impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunks<'a, T, N> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T; N]> {
- self.iter.next_back()
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- self.iter.nth_back(n)
- }
-}
-
-#[unstable(feature = "array_chunks", issue = "74985")]
-impl<T, const N: usize> ExactSizeIterator for ArrayChunks<'_, T, N> {
- fn is_empty(&self) -> bool {
- self.iter.is_empty()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T, const N: usize> TrustedLen for ArrayChunks<'_, T, N> {}
-
-#[unstable(feature = "array_chunks", issue = "74985")]
-impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
-
-#[doc(hidden)]
-#[unstable(feature = "array_chunks", issue = "74985")]
-unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
-/// time), starting at the end of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last slice
-/// of the iteration will be the remainder.
-///
-/// This struct is created by the [`rchunks`] method on [slices].
-///
-/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rchunks", since = "1.31.0")]
-pub struct RChunks<'a, T: 'a> {
- v: &'a [T],
- chunk_size: usize,
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> Clone for RChunks<'_, T> {
- fn clone(&self) -> Self {
- RChunks { v: self.v, chunk_size: self.chunk_size }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> Iterator for RChunks<'a, T> {
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.v.is_empty() {
- None
- } else {
- let chunksz = cmp::min(self.v.len(), self.chunk_size);
- let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
- self.v = fst;
- Some(snd)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.v.is_empty() {
- (0, Some(0))
- } else {
- let n = self.v.len() / self.chunk_size;
- let rem = self.v.len() % self.chunk_size;
- let n = if rem > 0 { n + 1 } else { n };
- (n, Some(n))
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- let (end, overflow) = n.overflowing_mul(self.chunk_size);
- if end >= self.v.len() || overflow {
- self.v = &[];
- None
- } else {
- // Can't underflow because of the check above
- let end = self.v.len() - end;
- let start = match end.checked_sub(self.chunk_size) {
- Some(sum) => sum,
- None => 0,
- };
- let nth = &self.v[start..end];
- self.v = &self.v[0..start];
- Some(nth)
- }
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- if self.v.is_empty() {
- None
- } else {
- let rem = self.v.len() % self.chunk_size;
- let end = if rem == 0 { self.chunk_size } else { rem };
- Some(&self.v[0..end])
- }
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let end = self.v.len() - idx * self.chunk_size;
- let start = match end.checked_sub(self.chunk_size) {
- None => 0,
- Some(start) => start,
- };
- // SAFETY: mostly identical to `Chunks::get_unchecked`.
- unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.v.is_empty() {
- None
- } else {
- let remainder = self.v.len() % self.chunk_size;
- let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
- let (fst, snd) = self.v.split_at(chunksz);
- self.v = snd;
- Some(fst)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &[];
- None
- } else {
- // can't underflow because `n < len`
- let offset_from_end = (len - 1 - n) * self.chunk_size;
- let end = self.v.len() - offset_from_end;
- let start = end.saturating_sub(self.chunk_size);
- let nth_back = &self.v[start..end];
- self.v = &self.v[end..];
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> ExactSizeIterator for RChunks<'_, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for RChunks<'_, T> {}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> FusedIterator for RChunks<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
-/// elements at a time), starting at the end of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last slice
-/// of the iteration will be the remainder.
-///
-/// This struct is created by the [`rchunks_mut`] method on [slices].
-///
-/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rchunks", since = "1.31.0")]
-pub struct RChunksMut<'a, T: 'a> {
- v: &'a mut [T],
- chunk_size: usize,
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> Iterator for RChunksMut<'a, T> {
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.v.is_empty() {
- None
- } else {
- let sz = cmp::min(self.v.len(), self.chunk_size);
- let tmp = mem::replace(&mut self.v, &mut []);
- let tmp_len = tmp.len();
- let (head, tail) = tmp.split_at_mut(tmp_len - sz);
- self.v = head;
- Some(tail)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.v.is_empty() {
- (0, Some(0))
- } else {
- let n = self.v.len() / self.chunk_size;
- let rem = self.v.len() % self.chunk_size;
- let n = if rem > 0 { n + 1 } else { n };
- (n, Some(n))
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
- let (end, overflow) = n.overflowing_mul(self.chunk_size);
- if end >= self.v.len() || overflow {
- self.v = &mut [];
- None
- } else {
- // Can't underflow because of the check above
- let end = self.v.len() - end;
- let start = match end.checked_sub(self.chunk_size) {
- Some(sum) => sum,
- None => 0,
- };
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(start);
- let (nth, _) = tail.split_at_mut(end - start);
- self.v = head;
- Some(nth)
- }
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- if self.v.is_empty() {
- None
- } else {
- let rem = self.v.len() % self.chunk_size;
- let end = if rem == 0 { self.chunk_size } else { rem };
- Some(&mut self.v[0..end])
- }
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let end = self.v.len() - idx * self.chunk_size;
- let start = match end.checked_sub(self.chunk_size) {
- None => 0,
- Some(start) => start,
- };
- // SAFETY: see comments for `RChunks::get_unchecked` and `ChunksMut::get_unchecked`
- unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.v.is_empty() {
- None
- } else {
- let remainder = self.v.len() % self.chunk_size;
- let sz = if remainder != 0 { remainder } else { self.chunk_size };
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(sz);
- self.v = tail;
- Some(head)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &mut [];
- None
- } else {
- // can't underflow because `n < len`
- let offset_from_end = (len - 1 - n) * self.chunk_size;
- let end = self.v.len() - offset_from_end;
- let start = end.saturating_sub(self.chunk_size);
- let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
- let (_, nth_back) = tmp.split_at_mut(start);
- self.v = tail;
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> FusedIterator for RChunksMut<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
-/// time), starting at the end of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last
-/// up to `chunk_size-1` elements will be omitted but can be retrieved from
-/// the [`remainder`] function from the iterator.
-///
-/// This struct is created by the [`rchunks_exact`] method on [slices].
-///
-/// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
-/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rchunks", since = "1.31.0")]
-pub struct RChunksExact<'a, T: 'a> {
- v: &'a [T],
- rem: &'a [T],
- chunk_size: usize,
-}
-
-impl<'a, T> RChunksExact<'a, T> {
- /// Returns the remainder of the original slice that is not going to be
- /// returned by the iterator. The returned slice has at most `chunk_size-1`
- /// elements.
- #[stable(feature = "rchunks", since = "1.31.0")]
- pub fn remainder(&self) -> &'a [T] {
- self.rem
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> Clone for RChunksExact<'a, T> {
- fn clone(&self) -> RChunksExact<'a, T> {
- RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> Iterator for RChunksExact<'a, T> {
- type Item = &'a [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
- self.v = fst;
- Some(snd)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let n = self.v.len() / self.chunk_size;
- (n, Some(n))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- let (end, overflow) = n.overflowing_mul(self.chunk_size);
- if end >= self.v.len() || overflow {
- self.v = &[];
- None
- } else {
- let (fst, _) = self.v.split_at(self.v.len() - end);
- self.v = fst;
- self.next()
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<Self::Item> {
- self.next_back()
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let end = self.v.len() - idx * self.chunk_size;
- let start = end - self.chunk_size;
- // SAFETY:
- // SAFETY: mostmy identical to `Chunks::get_unchecked`.
- unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let (fst, snd) = self.v.split_at(self.chunk_size);
- self.v = snd;
- Some(fst)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &[];
- None
- } else {
- // now that we know that `n` corresponds to a chunk,
- // none of these operations can underflow/overflow
- let offset = (len - n) * self.chunk_size;
- let start = self.v.len() - offset;
- let end = start + self.chunk_size;
- let nth_back = &self.v[start..end];
- self.v = &self.v[end..];
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
- fn is_empty(&self) -> bool {
- self.v.is_empty()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> FusedIterator for RChunksExact<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
-/// elements at a time), starting at the end of the slice.
-///
-/// When the slice len is not evenly divided by the chunk size, the last up to
-/// `chunk_size-1` elements will be omitted but can be retrieved from the
-/// [`into_remainder`] function from the iterator.
-///
-/// This struct is created by the [`rchunks_exact_mut`] method on [slices].
-///
-/// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
-/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
-/// [slices]: ../../std/primitive.slice.html
-#[derive(Debug)]
-#[stable(feature = "rchunks", since = "1.31.0")]
-pub struct RChunksExactMut<'a, T: 'a> {
- v: &'a mut [T],
- rem: &'a mut [T],
- chunk_size: usize,
-}
-
-impl<'a, T> RChunksExactMut<'a, T> {
- /// Returns the remainder of the original slice that is not going to be
- /// returned by the iterator. The returned slice has at most `chunk_size-1`
- /// elements.
- #[stable(feature = "rchunks", since = "1.31.0")]
- pub fn into_remainder(self) -> &'a mut [T] {
- self.rem
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> Iterator for RChunksExactMut<'a, T> {
- type Item = &'a mut [T];
-
- #[inline]
- fn next(&mut self) -> Option<&'a mut [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let tmp_len = tmp.len();
- let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
- self.v = head;
- Some(tail)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let n = self.v.len() / self.chunk_size;
- (n, Some(n))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.len()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
- let (end, overflow) = n.overflowing_mul(self.chunk_size);
- if end >= self.v.len() || overflow {
- self.v = &mut [];
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let tmp_len = tmp.len();
- let (fst, _) = tmp.split_at_mut(tmp_len - end);
- self.v = fst;
- self.next()
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<Self::Item> {
- self.next_back()
- }
-
- #[doc(hidden)]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
- let end = self.v.len() - idx * self.chunk_size;
- let start = end - self.chunk_size;
- // SAFETY: see comments for `RChunksMut::get_unchecked`.
- unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut [T]> {
- if self.v.len() < self.chunk_size {
- None
- } else {
- let tmp = mem::replace(&mut self.v, &mut []);
- let (head, tail) = tmp.split_at_mut(self.chunk_size);
- self.v = tail;
- Some(head)
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.len();
- if n >= len {
- self.v = &mut [];
- None
- } else {
- // now that we know that `n` corresponds to a chunk,
- // none of these operations can underflow/overflow
- let offset = (len - n) * self.chunk_size;
- let start = self.v.len() - offset;
- let end = start + self.chunk_size;
- let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
- let (_, nth_back) = tmp.split_at_mut(start);
- self.v = tail;
- Some(nth_back)
- }
- }
-}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
- fn is_empty(&self) -> bool {
- self.v.is_empty()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
-
-#[stable(feature = "rchunks", since = "1.31.0")]
-impl<T> FusedIterator for RChunksExactMut<'_, T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-//
-// Free functions
-//
-
-/// Forms a slice from a pointer and a length.
-///
-/// The `len` argument is the number of **elements**, not the number of bytes.
-///
-/// # Safety
-///
-/// Behavior is undefined if any of the following conditions are violated:
-///
-/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
-/// and it must be properly aligned. This means in particular:
-///
-/// * The entire memory range of this slice must be contained within a single allocated object!
-/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
-/// for an example incorrectly not taking this into account.
-/// * `data` must be non-null and aligned even for zero-length slices. One
-/// reason for this is that enum layout optimizations may rely on references
-/// (including slices of any length) being aligned and non-null to distinguish
-/// them from other data. You can obtain a pointer that is usable as `data`
-/// for zero-length slices using [`NonNull::dangling()`].
-///
-/// * The memory referenced by the returned slice must not be mutated for the duration
-/// of lifetime `'a`, except inside an `UnsafeCell`.
-///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
-/// See the safety documentation of [`pointer::offset`].
-///
-/// # Caveat
-///
-/// The lifetime for the returned slice is inferred from its usage. To
-/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
-/// source lifetime is safe in the context, such as by providing a helper
-/// function taking the lifetime of a host value for the slice, or by explicit
-/// annotation.
-///
-/// # Examples
-///
-/// ```
-/// use std::slice;
-///
-/// // manifest a slice for a single element
-/// let x = 42;
-/// let ptr = &x as *const _;
-/// let slice = unsafe { slice::from_raw_parts(ptr, 1) };
-/// assert_eq!(slice[0], 42);
-/// ```
-///
-/// ### Incorrect usage
-///
-/// The following `join_slices` function is **unsound** ā ļø
-///
-/// ```rust,no_run
-/// use std::slice;
-///
-/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
-/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
-/// let snd_start = snd.as_ptr();
-/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
-/// unsafe {
-/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
-/// // still be contained within _different allocated objects_, in which case
-/// // creating this slice is undefined behavior.
-/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
-/// }
-/// }
-///
-/// fn main() {
-/// // `a` and `b` are different allocated objects...
-/// let a = 42;
-/// let b = 27;
-/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
-/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
-/// }
-/// ```
-///
-/// [valid]: ../../std/ptr/index.html#safety
-/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
-/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
- debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
- debug_assert!(
- mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
- "attempt to create slice covering at least half the address space"
- );
- // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
- unsafe { &*ptr::slice_from_raw_parts(data, len) }
-}
-
-/// Performs the same functionality as [`from_raw_parts`], except that a
-/// mutable slice is returned.
-///
-/// # Safety
-///
-/// Behavior is undefined if any of the following conditions are violated:
-///
-/// * `data` must be [valid] for boths reads and writes for `len * mem::size_of::<T>()` many bytes,
-/// and it must be properly aligned. This means in particular:
-///
-/// * The entire memory range of this slice must be contained within a single allocated object!
-/// Slices can never span across multiple allocated objects.
-/// * `data` must be non-null and aligned even for zero-length slices. One
-/// reason for this is that enum layout optimizations may rely on references
-/// (including slices of any length) being aligned and non-null to distinguish
-/// them from other data. You can obtain a pointer that is usable as `data`
-/// for zero-length slices using [`NonNull::dangling()`].
-///
-/// * The memory referenced by the returned slice must not be accessed through any other pointer
-/// (not derived from the return value) for the duration of lifetime `'a`.
-/// Both read and write accesses are forbidden.
-///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
-/// See the safety documentation of [`pointer::offset`].
-///
-/// [valid]: ../../std/ptr/index.html#safety
-/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
-/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
-/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
- debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
- debug_assert!(
- mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
- "attempt to create slice covering at least half the address space"
- );
- // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
- unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
-}
-
-/// Converts a reference to T into a slice of length 1 (without copying).
-#[stable(feature = "from_ref", since = "1.28.0")]
-pub fn from_ref<T>(s: &T) -> &[T] {
- // SAFETY: a reference is guaranteed to be valid for reads. The returned
- // reference cannot be mutated as it is an immutable reference.
- // `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
- // Thus the call to `from_raw_parts` is safe.
- unsafe { from_raw_parts(s, 1) }
-}
-
-/// Converts a reference to T into a slice of length 1 (without copying).
-#[stable(feature = "from_ref", since = "1.28.0")]
-pub fn from_mut<T>(s: &mut T) -> &mut [T] {
- // SAFETY: a mutable reference is guaranteed to be valid for writes.
- // The reference cannot be accessed by another pointer as it is an mutable reference.
- // `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
- // Thus the call to `from_raw_parts_mut` is safe.
- unsafe { from_raw_parts_mut(s, 1) }
-}
-
-// This function is public only because there is no other way to unit test heapsort.
-#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
-#[doc(hidden)]
-pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
-where
- F: FnMut(&T, &T) -> bool,
-{
- sort::heapsort(v, &mut is_less);
-}
-
-//
-// Comparison traits
-//
-
-extern "C" {
- /// Calls implementation provided memcmp.
- ///
- /// Interprets the data as u8.
- ///
- /// Returns 0 for equal, < 0 for less than and > 0 for greater
- /// than.
- // FIXME(#32610): Return type should be c_int
- fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B> PartialEq<[B]> for [A]
-where
- A: PartialEq<B>,
-{
- fn eq(&self, other: &[B]) -> bool {
- SlicePartialEq::equal(self, other)
- }
-
- fn ne(&self, other: &[B]) -> bool {
- SlicePartialEq::not_equal(self, other)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq> Eq for [T] {}
-
-/// Implements comparison of vectors lexicographically.
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Ord> Ord for [T] {
- fn cmp(&self, other: &[T]) -> Ordering {
- SliceOrd::compare(self, other)
- }
-}
-
-/// Implements comparison of vectors lexicographically.
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PartialOrd> PartialOrd for [T] {
- fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
- SlicePartialOrd::partial_compare(self, other)
- }
-}
-
-#[doc(hidden)]
-// intermediate trait for specialization of slice's PartialEq
-trait SlicePartialEq<B> {
- fn equal(&self, other: &[B]) -> bool;
-
- fn not_equal(&self, other: &[B]) -> bool {
- !self.equal(other)
- }
-}
-
-// Generic slice equality
-impl<A, B> SlicePartialEq<B> for [A]
-where
- A: PartialEq<B>,
-{
- default fn equal(&self, other: &[B]) -> bool {
- if self.len() != other.len() {
- return false;
- }
-
- self.iter().zip(other.iter()).all(|(x, y)| x == y)
- }
-}
-
-// Use an equal-pointer optimization when types are `Eq`
-// We can't make `A` and `B` the same type because `min_specialization` won't
-// allow it.
-impl<A, B> SlicePartialEq<B> for [A]
-where
- A: MarkerEq<B>,
-{
- default fn equal(&self, other: &[B]) -> bool {
- if self.len() != other.len() {
- return false;
- }
-
- // While performance would suffer if `guaranteed_eq` just returned `false`
- // for all arguments, correctness and return value of this function are not affected.
- if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) {
- return true;
- }
-
- self.iter().zip(other.iter()).all(|(x, y)| x == y)
- }
-}
-
-// Use memcmp for bytewise equality when the types allow
-impl<A, B> SlicePartialEq<B> for [A]
-where
- A: BytewiseEquality<B>,
-{
- fn equal(&self, other: &[B]) -> bool {
- if self.len() != other.len() {
- return false;
- }
-
- // While performance would suffer if `guaranteed_eq` just returned `false`
- // for all arguments, correctness and return value of this function are not affected.
- if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) {
- return true;
- }
- // SAFETY: `self` and `other` are references and are thus guaranteed to be valid.
- // The two slices have been checked to have the same size above.
- unsafe {
- let size = mem::size_of_val(self);
- memcmp(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0
- }
- }
-}
-
-#[doc(hidden)]
-// intermediate trait for specialization of slice's PartialOrd
-trait SlicePartialOrd: Sized {
- fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>;
-}
-
-impl<A: PartialOrd> SlicePartialOrd for A {
- default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
- let l = cmp::min(left.len(), right.len());
-
- // Slice to the loop iteration range to enable bound check
- // elimination in the compiler
- let lhs = &left[..l];
- let rhs = &right[..l];
-
- for i in 0..l {
- match lhs[i].partial_cmp(&rhs[i]) {
- Some(Ordering::Equal) => (),
- non_eq => return non_eq,
- }
- }
-
- left.len().partial_cmp(&right.len())
- }
-}
-
-// This is the impl that we would like to have. Unfortunately it's not sound.
-// See `partial_ord_slice.rs`.
-/*
-impl<A> SlicePartialOrd for A
-where
- A: Ord,
-{
- default fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
- Some(SliceOrd::compare(left, right))
- }
-}
-*/
-
-impl<A: AlwaysApplicableOrd> SlicePartialOrd for A {
- fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
- Some(SliceOrd::compare(left, right))
- }
-}
-
-#[rustc_specialization_trait]
-trait AlwaysApplicableOrd: SliceOrd + Ord {}
-
-macro_rules! always_applicable_ord {
- ($([$($p:tt)*] $t:ty,)*) => {
- $(impl<$($p)*> AlwaysApplicableOrd for $t {})*
- }
-}
-
-always_applicable_ord! {
- [] u8, [] u16, [] u32, [] u64, [] u128, [] usize,
- [] i8, [] i16, [] i32, [] i64, [] i128, [] isize,
- [] bool, [] char,
- [T: ?Sized] *const T, [T: ?Sized] *mut T,
- [T: AlwaysApplicableOrd] &T,
- [T: AlwaysApplicableOrd] &mut T,
- [T: AlwaysApplicableOrd] Option<T>,
-}
-
-#[doc(hidden)]
-// intermediate trait for specialization of slice's Ord
-trait SliceOrd: Sized {
- fn compare(left: &[Self], right: &[Self]) -> Ordering;
-}
-
-impl<A: Ord> SliceOrd for A {
- default fn compare(left: &[Self], right: &[Self]) -> Ordering {
- let l = cmp::min(left.len(), right.len());
-
- // Slice to the loop iteration range to enable bound check
- // elimination in the compiler
- let lhs = &left[..l];
- let rhs = &right[..l];
-
- for i in 0..l {
- match lhs[i].cmp(&rhs[i]) {
- Ordering::Equal => (),
- non_eq => return non_eq,
- }
- }
-
- left.len().cmp(&right.len())
- }
-}
-
-// memcmp compares a sequence of unsigned bytes lexicographically.
-// this matches the order we want for [u8], but no others (not even [i8]).
-impl SliceOrd for u8 {
- #[inline]
- fn compare(left: &[Self], right: &[Self]) -> Ordering {
- let order =
- // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
- // We use the minimum of both lengths which guarantees that both regions are
- // valid for reads in that interval.
- unsafe { memcmp(left.as_ptr(), right.as_ptr(), cmp::min(left.len(), right.len())) };
- if order == 0 {
- left.len().cmp(&right.len())
- } else if order < 0 {
- Less
- } else {
- Greater
- }
- }
-}
-
-// Hack to allow specializing on `Eq` even though `Eq` has a method.
-#[rustc_unsafe_specialization_marker]
-trait MarkerEq<T>: PartialEq<T> {}
-
-impl<T: Eq> MarkerEq<T> for T {}
-
-#[doc(hidden)]
-/// Trait implemented for types that can be compared for equality using
-/// their bytewise representation
-#[rustc_specialization_trait]
-trait BytewiseEquality<T>: MarkerEq<T> + Copy {}
-
-macro_rules! impl_marker_for {
- ($traitname:ident, $($ty:ty)*) => {
- $(
- impl $traitname<$ty> for $ty { }
- )*
- }
-}
-
-impl_marker_for!(BytewiseEquality,
- u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize char bool);
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-trait SliceContains: Sized {
- fn slice_contains(&self, x: &[Self]) -> bool;
-}
-
-impl<T> SliceContains for T
-where
- T: PartialEq,
-{
- default fn slice_contains(&self, x: &[Self]) -> bool {
- x.iter().any(|y| *y == *self)
- }
-}
-
-impl SliceContains for u8 {
- fn slice_contains(&self, x: &[Self]) -> bool {
- memchr::memchr(*self, x).is_some()
- }
-}
-
-impl SliceContains for i8 {
- fn slice_contains(&self, x: &[Self]) -> bool {
- let byte = *self as u8;
- // SAFETY: `i8` and `u8` have the same memory layout, thus casting `x.as_ptr()`
- // as `*const u8` is safe. The `x.as_ptr()` comes from a reference and is thus guaranteed
- // to be valid for reads for the length of the slice `x.len()`, which cannot be larger
- // than `isize::MAX`. The returned slice is never mutated.
- let bytes: &[u8] = unsafe { from_raw_parts(x.as_ptr() as *const u8, x.len()) };
- memchr::memchr(byte, bytes).is_some()
- }
-}
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
new file mode 100644
index 0000000..0920930
--- /dev/null
+++ b/library/core/src/slice/raw.rs
@@ -0,0 +1,151 @@
+//! Free functions to create `&[T]` and `&mut [T]`.
+
+use crate::array;
+use crate::intrinsics::is_aligned_and_not_null;
+use crate::mem;
+use crate::ptr;
+
+/// Forms a slice from a pointer and a length.
+///
+/// The `len` argument is the number of **elements**, not the number of bytes.
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+/// and it must be properly aligned. This means in particular:
+///
+/// * The entire memory range of this slice must be contained within a single allocated object!
+/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
+/// for an example incorrectly not taking this into account.
+/// * `data` must be non-null and aligned even for zero-length slices. One
+/// reason for this is that enum layout optimizations may rely on references
+/// (including slices of any length) being aligned and non-null to distinguish
+/// them from other data. You can obtain a pointer that is usable as `data`
+/// for zero-length slices using [`NonNull::dangling()`].
+///
+/// * `data` must point to `len` consecutive properly initialized values of type `T`.
+///
+/// * The memory referenced by the returned slice must not be mutated for the duration
+/// of lifetime `'a`, except inside an `UnsafeCell`.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// See the safety documentation of [`pointer::offset`].
+///
+/// # Caveat
+///
+/// The lifetime for the returned slice is inferred from its usage. To
+/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
+/// source lifetime is safe in the context, such as by providing a helper
+/// function taking the lifetime of a host value for the slice, or by explicit
+/// annotation.
+///
+/// # Examples
+///
+/// ```
+/// use std::slice;
+///
+/// // manifest a slice for a single element
+/// let x = 42;
+/// let ptr = &x as *const _;
+/// let slice = unsafe { slice::from_raw_parts(ptr, 1) };
+/// assert_eq!(slice[0], 42);
+/// ```
+///
+/// ### Incorrect usage
+///
+/// The following `join_slices` function is **unsound** ā ļø
+///
+/// ```rust,no_run
+/// use std::slice;
+///
+/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
+/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
+/// let snd_start = snd.as_ptr();
+/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
+/// unsafe {
+/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
+/// // still be contained within _different allocated objects_, in which case
+/// // creating this slice is undefined behavior.
+/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
+/// }
+/// }
+///
+/// fn main() {
+/// // `a` and `b` are different allocated objects...
+/// let a = 42;
+/// let b = 27;
+/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
+/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
+/// }
+/// ```
+///
+/// [valid]: ptr#safety
+/// [`NonNull::dangling()`]: ptr::NonNull::dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
+ debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
+ debug_assert!(
+ mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
+ "attempt to create slice covering at least half the address space"
+ );
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
+ unsafe { &*ptr::slice_from_raw_parts(data, len) }
+}
+
+/// Performs the same functionality as [`from_raw_parts`], except that a
+/// mutable slice is returned.
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `data` must be [valid] for boths reads and writes for `len * mem::size_of::<T>()` many bytes,
+/// and it must be properly aligned. This means in particular:
+///
+/// * The entire memory range of this slice must be contained within a single allocated object!
+/// Slices can never span across multiple allocated objects.
+/// * `data` must be non-null and aligned even for zero-length slices. One
+/// reason for this is that enum layout optimizations may rely on references
+/// (including slices of any length) being aligned and non-null to distinguish
+/// them from other data. You can obtain a pointer that is usable as `data`
+/// for zero-length slices using [`NonNull::dangling()`].
+///
+/// * `data` must point to `len` consecutive properly initialized values of type `T`.
+///
+/// * The memory referenced by the returned slice must not be accessed through any other pointer
+/// (not derived from the return value) for the duration of lifetime `'a`.
+/// Both read and write accesses are forbidden.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// See the safety documentation of [`pointer::offset`].
+///
+/// [valid]: ptr#safety
+/// [`NonNull::dangling()`]: ptr::NonNull::dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
+ debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
+ debug_assert!(
+ mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
+ "attempt to create slice covering at least half the address space"
+ );
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
+ unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
+}
+
+/// Converts a reference to T into a slice of length 1 (without copying).
+#[stable(feature = "from_ref", since = "1.28.0")]
+pub fn from_ref<T>(s: &T) -> &[T] {
+ array::from_ref(s)
+}
+
+/// Converts a reference to T into a slice of length 1 (without copying).
+#[stable(feature = "from_ref", since = "1.28.0")]
+pub fn from_mut<T>(s: &mut T) -> &mut [T] {
+ array::from_mut(s)
+}
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 972a33d..71d2c2c 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -180,7 +180,8 @@
/// Sorts `v` using heapsort, which guarantees *O*(*n* \* log(*n*)) worst-case.
#[cold]
-pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
+#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
+pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
where
F: FnMut(&T, &T) -> bool,
{
@@ -299,8 +300,8 @@
if start_l == end_l {
// Trace `block_l` elements from the left side.
- start_l = MaybeUninit::first_ptr_mut(&mut offsets_l);
- end_l = MaybeUninit::first_ptr_mut(&mut offsets_l);
+ start_l = MaybeUninit::slice_as_mut_ptr(&mut offsets_l);
+ end_l = MaybeUninit::slice_as_mut_ptr(&mut offsets_l);
let mut elem = l;
for i in 0..block_l {
@@ -325,8 +326,8 @@
if start_r == end_r {
// Trace `block_r` elements from the right side.
- start_r = MaybeUninit::first_ptr_mut(&mut offsets_r);
- end_r = MaybeUninit::first_ptr_mut(&mut offsets_r);
+ start_r = MaybeUninit::slice_as_mut_ptr(&mut offsets_r);
+ end_r = MaybeUninit::slice_as_mut_ptr(&mut offsets_r);
let mut elem = r;
for i in 0..block_r {
@@ -564,7 +565,7 @@
random
};
let mut gen_usize = || {
- if mem::size_of::<usize>() <= 4 {
+ if usize::BITS <= 32 {
gen_u32() as usize
} else {
(((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize
@@ -666,7 +667,7 @@
///
/// `limit` is the number of allowed imbalanced partitions before switching to `heapsort`. If zero,
/// this function will immediately switch to heapsort.
-fn recurse<'a, T, F>(mut v: &'a mut [T], is_less: &mut F, mut pred: Option<&'a T>, mut limit: usize)
+fn recurse<'a, T, F>(mut v: &'a mut [T], is_less: &mut F, mut pred: Option<&'a T>, mut limit: u32)
where
F: FnMut(&T, &T) -> bool,
{
@@ -762,7 +763,7 @@
}
// Limit the number of imbalanced partitions to `floor(log2(len)) + 1`.
- let limit = mem::size_of::<usize>() * 8 - v.len().leading_zeros() as usize;
+ let limit = usize::BITS - v.len().leading_zeros();
recurse(v, &mut is_less, None, limit);
}
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
new file mode 100644
index 0000000..de2a93f
--- /dev/null
+++ b/library/core/src/str/converts.rs
@@ -0,0 +1,192 @@
+//! Ways to create a `str` from bytes slice.
+
+use crate::mem;
+
+use super::validations::run_utf8_validation;
+use super::Utf8Error;
+
+/// Converts a slice of bytes to a string slice.
+///
+/// A string slice ([`&str`]) is made of bytes ([`u8`]), and a byte slice
+/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts between
+/// the two. Not all byte slices are valid string slices, however: [`&str`] requires
+/// that it is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
+/// UTF-8, and then does the conversion.
+///
+/// [`&str`]: str
+/// [byteslice]: ../../std/primitive.slice.html
+///
+/// If you are sure that the byte slice is valid UTF-8, and you don't want to
+/// incur the overhead of the validity check, there is an unsafe version of
+/// this function, [`from_utf8_unchecked`], which has the same
+/// behavior but skips the check.
+///
+/// If you need a `String` instead of a `&str`, consider
+/// [`String::from_utf8`][string].
+///
+/// [string]: ../../std/string/struct.String.html#method.from_utf8
+///
+/// Because you can stack-allocate a `[u8; N]`, and you can take a
+/// [`&[u8]`][byteslice] of it, this function is one way to have a
+/// stack-allocated string. There is an example of this in the
+/// examples section below.
+///
+/// [byteslice]: ../../std/primitive.slice.html
+///
+/// # Errors
+///
+/// Returns `Err` if the slice is not UTF-8 with a description as to why the
+/// provided slice is not UTF-8.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::str;
+///
+/// // some bytes, in a vector
+/// let sparkle_heart = vec![240, 159, 146, 150];
+///
+/// // We know these bytes are valid, so just use `unwrap()`.
+/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
+///
+/// assert_eq!("š", sparkle_heart);
+/// ```
+///
+/// Incorrect bytes:
+///
+/// ```
+/// use std::str;
+///
+/// // some invalid bytes, in a vector
+/// let sparkle_heart = vec![0, 159, 146, 150];
+///
+/// assert!(str::from_utf8(&sparkle_heart).is_err());
+/// ```
+///
+/// See the docs for [`Utf8Error`] for more details on the kinds of
+/// errors that can be returned.
+///
+/// A "stack allocated string":
+///
+/// ```
+/// use std::str;
+///
+/// // some bytes, in a stack-allocated array
+/// let sparkle_heart = [240, 159, 146, 150];
+///
+/// // We know these bytes are valid, so just use `unwrap()`.
+/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
+///
+/// assert_eq!("š", sparkle_heart);
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
+ run_utf8_validation(v)?;
+ // SAFETY: Just ran validation.
+ Ok(unsafe { from_utf8_unchecked(v) })
+}
+
+/// Converts a mutable slice of bytes to a mutable string slice.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::str;
+///
+/// // "Hello, Rust!" as a mutable vector
+/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
+///
+/// // As we know these bytes are valid, we can use `unwrap()`
+/// let outstr = str::from_utf8_mut(&mut hellorust).unwrap();
+///
+/// assert_eq!("Hello, Rust!", outstr);
+/// ```
+///
+/// Incorrect bytes:
+///
+/// ```
+/// use std::str;
+///
+/// // Some invalid bytes in a mutable vector
+/// let mut invalid = vec![128, 223];
+///
+/// assert!(str::from_utf8_mut(&mut invalid).is_err());
+/// ```
+/// See the docs for [`Utf8Error`] for more details on the kinds of
+/// errors that can be returned.
+#[stable(feature = "str_mut_extras", since = "1.20.0")]
+pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
+ run_utf8_validation(v)?;
+ // SAFETY: Just ran validation.
+ Ok(unsafe { from_utf8_unchecked_mut(v) })
+}
+
+/// Converts a slice of bytes to a string slice without checking
+/// that the string contains valid UTF-8.
+///
+/// See the safe version, [`from_utf8`], for more information.
+///
+/// # Safety
+///
+/// This function is unsafe because it does not check that the bytes passed to
+/// it are valid UTF-8. If this constraint is violated, undefined behavior
+/// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
+///
+/// [`&str`]: str
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::str;
+///
+/// // some bytes, in a vector
+/// let sparkle_heart = vec![240, 159, 146, 150];
+///
+/// let sparkle_heart = unsafe {
+/// str::from_utf8_unchecked(&sparkle_heart)
+/// };
+///
+/// assert_eq!("š", sparkle_heart);
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")]
+#[allow_internal_unstable(const_fn_transmute)]
+pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
+ // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
+ // Also relies on `&str` and `&[u8]` having the same layout.
+ unsafe { mem::transmute(v) }
+}
+
+/// Converts a slice of bytes to a string slice without checking
+/// that the string contains valid UTF-8; mutable version.
+///
+/// See the immutable version, [`from_utf8_unchecked()`] for more information.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::str;
+///
+/// let mut heart = vec![240, 159, 146, 150];
+/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
+///
+/// assert_eq!("š", heart);
+/// ```
+#[inline]
+#[stable(feature = "str_mut_extras", since = "1.20.0")]
+pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
+ // SAFETY: the caller must guarantee that the bytes `v`
+ // are valid UTF-8, thus the cast to `*mut str` is safe.
+ // Also, the pointer dereference is safe because that pointer
+ // comes from a reference which is guaranteed to be valid for writes.
+ unsafe { &mut *(v as *mut [u8] as *mut str) }
+}
diff --git a/library/core/src/str/error.rs b/library/core/src/str/error.rs
new file mode 100644
index 0000000..427f720
--- /dev/null
+++ b/library/core/src/str/error.rs
@@ -0,0 +1,129 @@
+//! Defines utf8 error type.
+
+use crate::fmt;
+
+/// Errors which can occur when attempting to interpret a sequence of [`u8`]
+/// as a string.
+///
+/// As such, the `from_utf8` family of functions and methods for both [`String`]s
+/// and [`&str`]s make use of this error, for example.
+///
+/// [`String`]: ../../std/string/struct.String.html#method.from_utf8
+/// [`&str`]: super::from_utf8
+///
+/// # Examples
+///
+/// This error type’s methods can be used to create functionality
+/// similar to `String::from_utf8_lossy` without allocating heap memory:
+///
+/// ```
+/// fn from_utf8_lossy<F>(mut input: &[u8], mut push: F) where F: FnMut(&str) {
+/// loop {
+/// match std::str::from_utf8(input) {
+/// Ok(valid) => {
+/// push(valid);
+/// break
+/// }
+/// Err(error) => {
+/// let (valid, after_valid) = input.split_at(error.valid_up_to());
+/// unsafe {
+/// push(std::str::from_utf8_unchecked(valid))
+/// }
+/// push("\u{FFFD}");
+///
+/// if let Some(invalid_sequence_length) = error.error_len() {
+/// input = &after_valid[invalid_sequence_length..]
+/// } else {
+/// break
+/// }
+/// }
+/// }
+/// }
+/// }
+/// ```
+#[derive(Copy, Eq, PartialEq, Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Utf8Error {
+ pub(super) valid_up_to: usize,
+ pub(super) error_len: Option<u8>,
+}
+
+impl Utf8Error {
+ /// Returns the index in the given string up to which valid UTF-8 was
+ /// verified.
+ ///
+ /// It is the maximum index such that `from_utf8(&input[..index])`
+ /// would return `Ok(_)`.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use std::str;
+ ///
+ /// // some invalid bytes, in a vector
+ /// let sparkle_heart = vec![0, 159, 146, 150];
+ ///
+ /// // std::str::from_utf8 returns a Utf8Error
+ /// let error = str::from_utf8(&sparkle_heart).unwrap_err();
+ ///
+ /// // the second byte is invalid here
+ /// assert_eq!(1, error.valid_up_to());
+ /// ```
+ #[stable(feature = "utf8_error", since = "1.5.0")]
+ pub fn valid_up_to(&self) -> usize {
+ self.valid_up_to
+ }
+
+ /// Provides more information about the failure:
+ ///
+ /// * `None`: the end of the input was reached unexpectedly.
+ /// `self.valid_up_to()` is 1 to 3 bytes from the end of the input.
+ /// If a byte stream (such as a file or a network socket) is being decoded incrementally,
+ /// this could be a valid `char` whose UTF-8 byte sequence is spanning multiple chunks.
+ ///
+ /// * `Some(len)`: an unexpected byte was encountered.
+ /// The length provided is that of the invalid byte sequence
+ /// that starts at the index given by `valid_up_to()`.
+ /// Decoding should resume after that sequence
+ /// (after inserting a [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD]) in case of
+ /// lossy decoding.
+ ///
+ /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
+ #[stable(feature = "utf8_error_error_len", since = "1.20.0")]
+ pub fn error_len(&self) -> Option<usize> {
+ self.error_len.map(|len| len as usize)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for Utf8Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if let Some(error_len) = self.error_len {
+ write!(
+ f,
+ "invalid utf-8 sequence of {} bytes from index {}",
+ error_len, self.valid_up_to
+ )
+ } else {
+ write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to)
+ }
+ }
+}
+
+/// An error returned when parsing a `bool` using [`from_str`] fails
+///
+/// [`from_str`]: super::FromStr::from_str
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseBoolError {
+ pub(super) _priv: (),
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseBoolError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ "provided string was not `true` or `false`".fmt(f)
+ }
+}
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
new file mode 100644
index 0000000..27a67e2
--- /dev/null
+++ b/library/core/src/str/iter.rs
@@ -0,0 +1,1255 @@
+//! Iterators for `str` methods.
+
+use crate::char;
+use crate::fmt::{self, Write};
+use crate::iter::TrustedRandomAccess;
+use crate::iter::{Chain, FlatMap, Flatten};
+use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen};
+use crate::ops::Try;
+use crate::option;
+use crate::slice::{self, Split as SliceSplit};
+
+use super::from_utf8_unchecked;
+use super::pattern::Pattern;
+use super::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
+use super::validations::{next_code_point, next_code_point_reverse, utf8_is_cont_byte};
+use super::LinesAnyMap;
+use super::{BytesIsNotEmpty, UnsafeBytesToStr};
+use super::{CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode};
+use super::{IsAsciiWhitespace, IsNotEmpty, IsWhitespace};
+
+/// An iterator over the [`char`]s of a string slice.
+///
+///
+/// This struct is created by the [`chars`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`char`]: prim@char
+/// [`chars`]: str::chars
+#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Chars<'a> {
+ pub(super) iter: slice::Iter<'a, u8>,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Iterator for Chars<'a> {
+ type Item = char;
+
+ #[inline]
+ fn next(&mut self) -> Option<char> {
+ next_code_point(&mut self.iter).map(|ch| {
+ // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
+ unsafe { char::from_u32_unchecked(ch) }
+ })
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ // length in `char` is equal to the number of non-continuation bytes
+ let bytes_len = self.iter.len();
+ let mut cont_bytes = 0;
+ for &byte in self.iter {
+ cont_bytes += utf8_is_cont_byte(byte) as usize;
+ }
+ bytes_len - cont_bytes
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.iter.len();
+ // `(len + 3)` can't overflow, because we know that the `slice::Iter`
+ // belongs to a slice in memory which has a maximum length of
+ // `isize::MAX` (that's well below `usize::MAX`).
+ ((len + 3) / 4, Some(len))
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<char> {
+ // No need to go through the entire string.
+ self.next_back()
+ }
+}
+
+#[stable(feature = "chars_debug_impl", since = "1.38.0")]
+impl fmt::Debug for Chars<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Chars(")?;
+ f.debug_list().entries(self.clone()).finish()?;
+ write!(f, ")")?;
+ Ok(())
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> DoubleEndedIterator for Chars<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<char> {
+ next_code_point_reverse(&mut self.iter).map(|ch| {
+ // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
+ unsafe { char::from_u32_unchecked(ch) }
+ })
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for Chars<'_> {}
+
+impl<'a> Chars<'a> {
+ /// Views the underlying data as a subslice of the original data.
+ ///
+ /// This has the same lifetime as the original slice, and so the
+ /// iterator can continue to be used while this exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut chars = "abc".chars();
+ ///
+ /// assert_eq!(chars.as_str(), "abc");
+ /// chars.next();
+ /// assert_eq!(chars.as_str(), "bc");
+ /// chars.next();
+ /// chars.next();
+ /// assert_eq!(chars.as_str(), "");
+ /// ```
+ #[stable(feature = "iter_to_slice", since = "1.4.0")]
+ #[inline]
+ pub fn as_str(&self) -> &'a str {
+ // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
+ unsafe { from_utf8_unchecked(self.iter.as_slice()) }
+ }
+}
+
+/// An iterator over the [`char`]s of a string slice, and their positions.
+///
+/// This struct is created by the [`char_indices`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`char`]: prim@char
+/// [`char_indices`]: str::char_indices
+#[derive(Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct CharIndices<'a> {
+ pub(super) front_offset: usize,
+ pub(super) iter: Chars<'a>,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Iterator for CharIndices<'a> {
+ type Item = (usize, char);
+
+ #[inline]
+ fn next(&mut self) -> Option<(usize, char)> {
+ let pre_len = self.iter.iter.len();
+ match self.iter.next() {
+ None => None,
+ Some(ch) => {
+ let index = self.front_offset;
+ let len = self.iter.iter.len();
+ self.front_offset += pre_len - len;
+ Some((index, ch))
+ }
+ }
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<(usize, char)> {
+ // No need to go through the entire string.
+ self.next_back()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> DoubleEndedIterator for CharIndices<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<(usize, char)> {
+ self.iter.next_back().map(|ch| {
+ let index = self.front_offset + self.iter.iter.len();
+ (index, ch)
+ })
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for CharIndices<'_> {}
+
+impl<'a> CharIndices<'a> {
+ /// Views the underlying data as a subslice of the original data.
+ ///
+ /// This has the same lifetime as the original slice, and so the
+ /// iterator can continue to be used while this exists.
+ #[stable(feature = "iter_to_slice", since = "1.4.0")]
+ #[inline]
+ pub fn as_str(&self) -> &'a str {
+ self.iter.as_str()
+ }
+}
+
+/// An iterator over the bytes of a string slice.
+///
+/// This struct is created by the [`bytes`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`bytes`]: str::bytes
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone, Debug)]
+pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for Bytes<'_> {
+ type Item = u8;
+
+ #[inline]
+ fn next(&mut self) -> Option<u8> {
+ self.0.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.0.count()
+ }
+
+ #[inline]
+ fn last(self) -> Option<Self::Item> {
+ self.0.last()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.0.nth(n)
+ }
+
+ #[inline]
+ fn all<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ self.0.all(f)
+ }
+
+ #[inline]
+ fn any<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ self.0.any(f)
+ }
+
+ #[inline]
+ fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ self.0.find(predicate)
+ }
+
+ #[inline]
+ fn position<P>(&mut self, predicate: P) -> Option<usize>
+ where
+ P: FnMut(Self::Item) -> bool,
+ {
+ self.0.position(predicate)
+ }
+
+ #[inline]
+ fn rposition<P>(&mut self, predicate: P) -> Option<usize>
+ where
+ P: FnMut(Self::Item) -> bool,
+ {
+ self.0.rposition(predicate)
+ }
+
+ #[inline]
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
+ // SAFETY: the caller must uphold the safety contract
+ // for `Iterator::__iterator_get_unchecked`.
+ unsafe { self.0.__iterator_get_unchecked(idx) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl DoubleEndedIterator for Bytes<'_> {
+ #[inline]
+ fn next_back(&mut self) -> Option<u8> {
+ self.0.next_back()
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ self.0.nth_back(n)
+ }
+
+ #[inline]
+ fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ self.0.rfind(predicate)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ExactSizeIterator for Bytes<'_> {
+ #[inline]
+ fn len(&self) -> usize {
+ self.0.len()
+ }
+
+ #[inline]
+ fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for Bytes<'_> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl TrustedLen for Bytes<'_> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl TrustedRandomAccess for Bytes<'_> {
+ fn may_have_side_effect() -> bool {
+ false
+ }
+}
+
+/// This macro generates a Clone impl for string pattern API
+/// wrapper types of the form X<'a, P>
+macro_rules! derive_pattern_clone {
+ (clone $t:ident with |$s:ident| $e:expr) => {
+ impl<'a, P> Clone for $t<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
+ {
+ fn clone(&self) -> Self {
+ let $s = self;
+ $e
+ }
+ }
+ };
+}
+
+/// This macro generates two public iterator structs
+/// wrapping a private internal one that makes use of the `Pattern` API.
+///
+/// For all patterns `P: Pattern<'a>` the following items will be
+/// generated (generics omitted):
+///
+/// struct $forward_iterator($internal_iterator);
+/// struct $reverse_iterator($internal_iterator);
+///
+/// impl Iterator for $forward_iterator
+/// { /* internal ends up calling Searcher::next_match() */ }
+///
+/// impl DoubleEndedIterator for $forward_iterator
+/// where P::Searcher: DoubleEndedSearcher
+/// { /* internal ends up calling Searcher::next_match_back() */ }
+///
+/// impl Iterator for $reverse_iterator
+/// where P::Searcher: ReverseSearcher
+/// { /* internal ends up calling Searcher::next_match_back() */ }
+///
+/// impl DoubleEndedIterator for $reverse_iterator
+/// where P::Searcher: DoubleEndedSearcher
+/// { /* internal ends up calling Searcher::next_match() */ }
+///
+/// The internal one is defined outside the macro, and has almost the same
+/// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
+/// `pattern::ReverseSearcher` for both forward and reverse iteration.
+///
+/// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
+/// `Pattern` might not return the same elements, so actually implementing
+/// `DoubleEndedIterator` for it would be incorrect.
+/// (See the docs in `str::pattern` for more details)
+///
+/// However, the internal struct still represents a single ended iterator from
+/// either end, and depending on pattern is also a valid double ended iterator,
+/// so the two wrapper structs implement `Iterator`
+/// and `DoubleEndedIterator` depending on the concrete pattern type, leading
+/// to the complex impls seen above.
+macro_rules! generate_pattern_iterators {
+ {
+ // Forward iterator
+ forward:
+ $(#[$forward_iterator_attribute:meta])*
+ struct $forward_iterator:ident;
+
+ // Reverse iterator
+ reverse:
+ $(#[$reverse_iterator_attribute:meta])*
+ struct $reverse_iterator:ident;
+
+ // Stability of all generated items
+ stability:
+ $(#[$common_stability_attribute:meta])*
+
+ // Internal almost-iterator that is being delegated to
+ internal:
+ $internal_iterator:ident yielding ($iterty:ty);
+
+ // Kind of delegation - either single ended or double ended
+ delegate $($t:tt)*
+ } => {
+ $(#[$forward_iterator_attribute])*
+ $(#[$common_stability_attribute])*
+ pub struct $forward_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+ {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple(stringify!($forward_iterator))
+ .field(&self.0)
+ .finish()
+ }
+ }
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
+ type Item = $iterty;
+
+ #[inline]
+ fn next(&mut self) -> Option<$iterty> {
+ self.0.next()
+ }
+ }
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> Clone for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
+ {
+ fn clone(&self) -> Self {
+ $forward_iterator(self.0.clone())
+ }
+ }
+
+ $(#[$reverse_iterator_attribute])*
+ $(#[$common_stability_attribute])*
+ pub struct $reverse_iterator<'a, P: Pattern<'a>>(pub(super) $internal_iterator<'a, P>);
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+ {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple(stringify!($reverse_iterator))
+ .field(&self.0)
+ .finish()
+ }
+ }
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> Iterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+ {
+ type Item = $iterty;
+
+ #[inline]
+ fn next(&mut self) -> Option<$iterty> {
+ self.0.next_back()
+ }
+ }
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> Clone for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: Clone>,
+ {
+ fn clone(&self) -> Self {
+ $reverse_iterator(self.0.clone())
+ }
+ }
+
+ #[stable(feature = "fused", since = "1.26.0")]
+ impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
+
+ #[stable(feature = "fused", since = "1.26.0")]
+ impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+ {}
+
+ generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
+ $forward_iterator,
+ $reverse_iterator, $iterty);
+ };
+ {
+ double ended; with $(#[$common_stability_attribute:meta])*,
+ $forward_iterator:ident,
+ $reverse_iterator:ident, $iterty:ty
+ } => {
+ $(#[$common_stability_attribute])*
+ impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
+ {
+ #[inline]
+ fn next_back(&mut self) -> Option<$iterty> {
+ self.0.next_back()
+ }
+ }
+
+ $(#[$common_stability_attribute])*
+ impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
+ where
+ P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
+ {
+ #[inline]
+ fn next_back(&mut self) -> Option<$iterty> {
+ self.0.next()
+ }
+ }
+ };
+ {
+ single ended; with $(#[$common_stability_attribute:meta])*,
+ $forward_iterator:ident,
+ $reverse_iterator:ident, $iterty:ty
+ } => {}
+}
+
+derive_pattern_clone! {
+ clone SplitInternal
+ with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
+}
+
+pub(super) struct SplitInternal<'a, P: Pattern<'a>> {
+ pub(super) start: usize,
+ pub(super) end: usize,
+ pub(super) matcher: P::Searcher,
+ pub(super) allow_trailing_empty: bool,
+ pub(super) finished: bool,
+}
+
+impl<'a, P> fmt::Debug for SplitInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInternal")
+ .field("start", &self.start)
+ .field("end", &self.end)
+ .field("matcher", &self.matcher)
+ .field("allow_trailing_empty", &self.allow_trailing_empty)
+ .field("finished", &self.finished)
+ .finish()
+ }
+}
+
+impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
+ #[inline]
+ fn get_end(&mut self) -> Option<&'a str> {
+ if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
+ self.finished = true;
+ // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
+ unsafe {
+ let string = self.matcher.haystack().get_unchecked(self.start..self.end);
+ Some(string)
+ }
+ } else {
+ None
+ }
+ }
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ if self.finished {
+ return None;
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match() {
+ // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
+ Some((a, b)) => unsafe {
+ let elt = haystack.get_unchecked(self.start..a);
+ self.start = b;
+ Some(elt)
+ },
+ None => self.get_end(),
+ }
+ }
+
+ #[inline]
+ fn next_inclusive(&mut self) -> Option<&'a str> {
+ if self.finished {
+ return None;
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match() {
+ // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
+ // and self.start is either the start of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ Some((_, b)) => unsafe {
+ let elt = haystack.get_unchecked(self.start..b);
+ self.start = b;
+ Some(elt)
+ },
+ None => self.get_end(),
+ }
+ }
+
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ if self.finished {
+ return None;
+ }
+
+ if !self.allow_trailing_empty {
+ self.allow_trailing_empty = true;
+ match self.next_back() {
+ Some(elt) if !elt.is_empty() => return Some(elt),
+ _ => {
+ if self.finished {
+ return None;
+ }
+ }
+ }
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match_back() {
+ // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
+ Some((a, b)) => unsafe {
+ let elt = haystack.get_unchecked(b..self.end);
+ self.end = a;
+ Some(elt)
+ },
+ // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
+ None => unsafe {
+ self.finished = true;
+ Some(haystack.get_unchecked(self.start..self.end))
+ },
+ }
+ }
+
+ #[inline]
+ fn next_back_inclusive(&mut self) -> Option<&'a str>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ if self.finished {
+ return None;
+ }
+
+ if !self.allow_trailing_empty {
+ self.allow_trailing_empty = true;
+ match self.next_back_inclusive() {
+ Some(elt) if !elt.is_empty() => return Some(elt),
+ _ => {
+ if self.finished {
+ return None;
+ }
+ }
+ }
+ }
+
+ let haystack = self.matcher.haystack();
+ match self.matcher.next_match_back() {
+ // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
+ // and self.end is either the end of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ Some((_, b)) => unsafe {
+ let elt = haystack.get_unchecked(b..self.end);
+ self.end = b;
+ Some(elt)
+ },
+ // SAFETY: self.start is either the start of the original string,
+ // or start of a substring that represents the part of the string that hasn't
+ // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
+ // self.end is either the end of the original string,
+ // or `b` was assigned to it, so it also lies on unicode boundary.
+ None => unsafe {
+ self.finished = true;
+ Some(haystack.get_unchecked(self.start..self.end))
+ },
+ }
+ }
+}
+
+generate_pattern_iterators! {
+ forward:
+ /// Created with the method [`split`].
+ ///
+ /// [`split`]: str::split
+ struct Split;
+ reverse:
+ /// Created with the method [`rsplit`].
+ ///
+ /// [`rsplit`]: str::rsplit
+ struct RSplit;
+ stability:
+ #[stable(feature = "rust1", since = "1.0.0")]
+ internal:
+ SplitInternal yielding (&'a str);
+ delegate double ended;
+}
+
+generate_pattern_iterators! {
+ forward:
+ /// Created with the method [`split_terminator`].
+ ///
+ /// [`split_terminator`]: str::split_terminator
+ struct SplitTerminator;
+ reverse:
+ /// Created with the method [`rsplit_terminator`].
+ ///
+ /// [`rsplit_terminator`]: str::rsplit_terminator
+ struct RSplitTerminator;
+ stability:
+ #[stable(feature = "rust1", since = "1.0.0")]
+ internal:
+ SplitInternal yielding (&'a str);
+ delegate double ended;
+}
+
+derive_pattern_clone! {
+ clone SplitNInternal
+ with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
+}
+
+pub(super) struct SplitNInternal<'a, P: Pattern<'a>> {
+ pub(super) iter: SplitInternal<'a, P>,
+ /// The number of splits remaining
+ pub(super) count: usize,
+}
+
+impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitNInternal")
+ .field("iter", &self.iter)
+ .field("count", &self.count)
+ .finish()
+ }
+}
+
+impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ match self.count {
+ 0 => None,
+ 1 => {
+ self.count = 0;
+ self.iter.get_end()
+ }
+ _ => {
+ self.count -= 1;
+ self.iter.next()
+ }
+ }
+ }
+
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ match self.count {
+ 0 => None,
+ 1 => {
+ self.count = 0;
+ self.iter.get_end()
+ }
+ _ => {
+ self.count -= 1;
+ self.iter.next_back()
+ }
+ }
+ }
+}
+
+generate_pattern_iterators! {
+ forward:
+ /// Created with the method [`splitn`].
+ ///
+ /// [`splitn`]: str::splitn
+ struct SplitN;
+ reverse:
+ /// Created with the method [`rsplitn`].
+ ///
+ /// [`rsplitn`]: str::rsplitn
+ struct RSplitN;
+ stability:
+ #[stable(feature = "rust1", since = "1.0.0")]
+ internal:
+ SplitNInternal yielding (&'a str);
+ delegate single ended;
+}
+
+derive_pattern_clone! {
+ clone MatchIndicesInternal
+ with |s| MatchIndicesInternal(s.0.clone())
+}
+
+pub(super) struct MatchIndicesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
+
+impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
+ }
+}
+
+impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
+ #[inline]
+ fn next(&mut self) -> Option<(usize, &'a str)> {
+ self.0
+ .next_match()
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
+ .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
+ }
+
+ #[inline]
+ fn next_back(&mut self) -> Option<(usize, &'a str)>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ self.0
+ .next_match_back()
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
+ .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
+ }
+}
+
+generate_pattern_iterators! {
+ forward:
+ /// Created with the method [`match_indices`].
+ ///
+ /// [`match_indices`]: str::match_indices
+ struct MatchIndices;
+ reverse:
+ /// Created with the method [`rmatch_indices`].
+ ///
+ /// [`rmatch_indices`]: str::rmatch_indices
+ struct RMatchIndices;
+ stability:
+ #[stable(feature = "str_match_indices", since = "1.5.0")]
+ internal:
+ MatchIndicesInternal yielding ((usize, &'a str));
+ delegate double ended;
+}
+
+derive_pattern_clone! {
+ clone MatchesInternal
+ with |s| MatchesInternal(s.0.clone())
+}
+
+pub(super) struct MatchesInternal<'a, P: Pattern<'a>>(pub(super) P::Searcher);
+
+impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
+where
+ P: Pattern<'a, Searcher: fmt::Debug>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("MatchesInternal").field(&self.0).finish()
+ }
+}
+
+impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
+ self.0.next_match().map(|(a, b)| unsafe {
+ // Indices are known to be on utf8 boundaries
+ self.0.haystack().get_unchecked(a..b)
+ })
+ }
+
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str>
+ where
+ P::Searcher: ReverseSearcher<'a>,
+ {
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
+ self.0.next_match_back().map(|(a, b)| unsafe {
+ // Indices are known to be on utf8 boundaries
+ self.0.haystack().get_unchecked(a..b)
+ })
+ }
+}
+
+generate_pattern_iterators! {
+ forward:
+ /// Created with the method [`matches`].
+ ///
+ /// [`matches`]: str::matches
+ struct Matches;
+ reverse:
+ /// Created with the method [`rmatches`].
+ ///
+ /// [`rmatches`]: str::rmatches
+ struct RMatches;
+ stability:
+ #[stable(feature = "str_matches", since = "1.2.0")]
+ internal:
+ MatchesInternal yielding (&'a str);
+ delegate double ended;
+}
+
+/// An iterator over the lines of a string, as string slices.
+///
+/// This struct is created with the [`lines`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`lines`]: str::lines
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone, Debug)]
+pub struct Lines<'a>(pub(super) Map<SplitTerminator<'a, char>, LinesAnyMap>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Iterator for Lines<'a> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.0.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<&'a str> {
+ self.next_back()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> DoubleEndedIterator for Lines<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.0.next_back()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for Lines<'_> {}
+
+/// Created with the method [`lines_any`].
+///
+/// [`lines_any`]: str::lines_any
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
+#[derive(Clone, Debug)]
+#[allow(deprecated)]
+pub struct LinesAny<'a>(pub(super) Lines<'a>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
+impl<'a> Iterator for LinesAny<'a> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.0.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
+impl<'a> DoubleEndedIterator for LinesAny<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.0.next_back()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+#[allow(deprecated)]
+impl FusedIterator for LinesAny<'_> {}
+
+/// An iterator over the non-whitespace substrings of a string,
+/// separated by any amount of whitespace.
+///
+/// This struct is created by the [`split_whitespace`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`split_whitespace`]: str::split_whitespace
+#[stable(feature = "split_whitespace", since = "1.1.0")]
+#[derive(Clone, Debug)]
+pub struct SplitWhitespace<'a> {
+ pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
+}
+
+/// An iterator over the non-ASCII-whitespace substrings of a string,
+/// separated by any amount of ASCII whitespace.
+///
+/// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`split_ascii_whitespace`]: str::split_ascii_whitespace
+#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
+#[derive(Clone, Debug)]
+pub struct SplitAsciiWhitespace<'a> {
+ pub(super) inner:
+ Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
+}
+
+/// An iterator over the substrings of a string,
+/// terminated by a substring matching to a predicate function
+/// Unlike `Split`, it contains the matched part as a terminator
+/// of the subslice.
+///
+/// This struct is created by the [`split_inclusive`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`split_inclusive`]: str::split_inclusive
+#[unstable(feature = "split_inclusive", issue = "72360")]
+pub struct SplitInclusive<'a, P: Pattern<'a>>(pub(super) SplitInternal<'a, P>);
+
+#[stable(feature = "split_whitespace", since = "1.1.0")]
+impl<'a> Iterator for SplitWhitespace<'a> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.inner.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<&'a str> {
+ self.next_back()
+ }
+}
+
+#[stable(feature = "split_whitespace", since = "1.1.0")]
+impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.inner.next_back()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for SplitWhitespace<'_> {}
+
+#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
+impl<'a> Iterator for SplitAsciiWhitespace<'a> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.inner.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<&'a str> {
+ self.next_back()
+ }
+}
+
+#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
+impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.inner.next_back()
+ }
+}
+
+#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
+impl FusedIterator for SplitAsciiWhitespace<'_> {}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
+ type Item = &'a str;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a str> {
+ self.0.next_inclusive()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SplitInclusive").field("0", &self.0).finish()
+ }
+}
+
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
+ fn clone(&self) -> Self {
+ SplitInclusive(self.0.clone())
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
+ for SplitInclusive<'a, P>
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a str> {
+ self.0.next_back_inclusive()
+ }
+}
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
+
+/// An iterator of [`u16`] over the string encoded as UTF-16.
+///
+/// This struct is created by the [`encode_utf16`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`encode_utf16`]: str::encode_utf16
+#[derive(Clone)]
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+pub struct EncodeUtf16<'a> {
+ pub(super) chars: Chars<'a>,
+ pub(super) extra: u16,
+}
+
+#[stable(feature = "collection_debug", since = "1.17.0")]
+impl fmt::Debug for EncodeUtf16<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.pad("EncodeUtf16 { .. }")
+ }
+}
+
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+impl<'a> Iterator for EncodeUtf16<'a> {
+ type Item = u16;
+
+ #[inline]
+ fn next(&mut self) -> Option<u16> {
+ if self.extra != 0 {
+ let tmp = self.extra;
+ self.extra = 0;
+ return Some(tmp);
+ }
+
+ let mut buf = [0; 2];
+ self.chars.next().map(|ch| {
+ let n = ch.encode_utf16(&mut buf).len();
+ if n == 2 {
+ self.extra = buf[1];
+ }
+ buf[0]
+ })
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, high) = self.chars.size_hint();
+ // every char gets either one u16 or two u16,
+ // so this iterator is between 1 or 2 times as
+ // long as the underlying iterator.
+ (low, high.and_then(|n| n.checked_mul(2)))
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl FusedIterator for EncodeUtf16<'_> {}
+
+/// The return type of [`str::escape_debug`].
+#[stable(feature = "str_escape", since = "1.34.0")]
+#[derive(Clone, Debug)]
+pub struct EscapeDebug<'a> {
+ pub(super) inner: Chain<
+ Flatten<option::IntoIter<char::EscapeDebug>>,
+ FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>,
+ >,
+}
+
+/// The return type of [`str::escape_default`].
+#[stable(feature = "str_escape", since = "1.34.0")]
+#[derive(Clone, Debug)]
+pub struct EscapeDefault<'a> {
+ pub(super) inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
+}
+
+/// The return type of [`str::escape_unicode`].
+#[stable(feature = "str_escape", since = "1.34.0")]
+#[derive(Clone, Debug)]
+pub struct EscapeUnicode<'a> {
+ pub(super) inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
+}
+
+macro_rules! escape_types_impls {
+ ($( $Name: ident ),+) => {$(
+ #[stable(feature = "str_escape", since = "1.34.0")]
+ impl<'a> fmt::Display for $Name<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.clone().try_for_each(|c| f.write_char(c))
+ }
+ }
+
+ #[stable(feature = "str_escape", since = "1.34.0")]
+ impl<'a> Iterator for $Name<'a> {
+ type Item = char;
+
+ #[inline]
+ fn next(&mut self) -> Option<char> { self.inner.next() }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+ Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+ {
+ self.inner.try_fold(init, fold)
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.inner.fold(init, fold)
+ }
+ }
+
+ #[stable(feature = "str_escape", since = "1.34.0")]
+ impl<'a> FusedIterator for $Name<'a> {}
+ )+}
+}
+
+escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 88b2bc5..720a35b 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -1,7 +1,9 @@
use crate::char;
use crate::fmt::{self, Write};
use crate::mem;
-use crate::str as core_str;
+
+use super::from_utf8_unchecked;
+use super::validations::utf8_char_width;
/// Lossy UTF-8 string.
#[unstable(feature = "str_internals", issue = "none")]
@@ -66,14 +68,14 @@
if byte < 128 {
} else {
- let w = core_str::utf8_char_width(byte);
+ let w = utf8_char_width(byte);
macro_rules! error {
() => {{
// SAFETY: We have checked up to `i` that source is valid UTF-8.
unsafe {
let r = Utf8LossyChunk {
- valid: core_str::from_utf8_unchecked(&self.source[0..i_]),
+ valid: from_utf8_unchecked(&self.source[0..i_]),
broken: &self.source[i_..i],
};
self.source = &self.source[i..];
@@ -133,7 +135,7 @@
let r = Utf8LossyChunk {
// SAFETY: We have checked that the entire source is valid UTF-8.
- valid: unsafe { core_str::from_utf8_unchecked(self.source) },
+ valid: unsafe { from_utf8_unchecked(self.source) },
broken: &[],
};
self.source = &[];
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index d7af5dd..3e18a4e 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -1,25 +1,23 @@
-// ignore-tidy-filelength
-
//! String manipulation.
//!
//! For more details, see the [`std::str`] module.
//!
-//! [`std::str`]: self
+//! [`std::str`]: ../../std/str/index.html
#![stable(feature = "rust1", since = "1.0.0")]
+mod converts;
+mod error;
+mod iter;
+mod traits;
+mod validations;
+
use self::pattern::Pattern;
use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
use crate::char;
-use crate::fmt::{self, Write};
-use crate::iter::TrustedRandomAccess;
-use crate::iter::{Chain, FlatMap, Flatten};
-use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen};
use crate::mem;
-use crate::ops::Try;
-use crate::option;
-use crate::slice::{self, SliceIndex, Split as SliceSplit};
+use crate::slice::{self, SliceIndex};
pub mod pattern;
@@ -27,2202 +25,57 @@
#[allow(missing_docs)]
pub mod lossy;
-/// Parse a value from a string
-///
-/// `FromStr`'s [`from_str`] method is often used implicitly, through
-/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
-///
-/// [`from_str`]: FromStr::from_str
-/// [`parse`]: str::parse
-///
-/// `FromStr` does not have a lifetime parameter, and so you can only parse types
-/// that do not contain a lifetime parameter themselves. In other words, you can
-/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
-/// contains an `i32`, but not one that contains an `&i32`.
-///
-/// # Examples
-///
-/// Basic implementation of `FromStr` on an example `Point` type:
-///
-/// ```
-/// use std::str::FromStr;
-/// use std::num::ParseIntError;
-///
-/// #[derive(Debug, PartialEq)]
-/// struct Point {
-/// x: i32,
-/// y: i32
-/// }
-///
-/// impl FromStr for Point {
-/// type Err = ParseIntError;
-///
-/// fn from_str(s: &str) -> Result<Self, Self::Err> {
-/// let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
-/// .split(',')
-/// .collect();
-///
-/// let x_fromstr = coords[0].parse::<i32>()?;
-/// let y_fromstr = coords[1].parse::<i32>()?;
-///
-/// Ok(Point { x: x_fromstr, y: y_fromstr })
-/// }
-/// }
-///
-/// let p = Point::from_str("(1,2)");
-/// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
-/// ```
#[stable(feature = "rust1", since = "1.0.0")]
-pub trait FromStr: Sized {
- /// The associated error which can be returned from parsing.
- #[stable(feature = "rust1", since = "1.0.0")]
- type Err;
+pub use converts::{from_utf8, from_utf8_unchecked};
- /// Parses a string `s` to return a value of this type.
- ///
- /// If parsing succeeds, return the value inside [`Ok`], otherwise
- /// when the string is ill-formatted return an error specific to the
- /// inside [`Err`]. The error type is specific to implementation of the trait.
- ///
- /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
- /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
- ///
- /// # Examples
- ///
- /// Basic usage with [`i32`][ithirtytwo], a type that implements `FromStr`:
- ///
- /// [ithirtytwo]: ../../std/primitive.i32.html
- ///
- /// ```
- /// use std::str::FromStr;
- ///
- /// let s = "5";
- /// let x = i32::from_str(s).unwrap();
- ///
- /// assert_eq!(5, x);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_str(s: &str) -> Result<Self, Self::Err>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl FromStr for bool {
- type Err = ParseBoolError;
-
- /// Parse a `bool` from a string.
- ///
- /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
- /// actually be parseable.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::str::FromStr;
- ///
- /// assert_eq!(FromStr::from_str("true"), Ok(true));
- /// assert_eq!(FromStr::from_str("false"), Ok(false));
- /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
- /// ```
- ///
- /// Note, in many cases, the `.parse()` method on `str` is more proper.
- ///
- /// ```
- /// assert_eq!("true".parse(), Ok(true));
- /// assert_eq!("false".parse(), Ok(false));
- /// assert!("not even a boolean".parse::<bool>().is_err());
- /// ```
- #[inline]
- fn from_str(s: &str) -> Result<bool, ParseBoolError> {
- match s {
- "true" => Ok(true),
- "false" => Ok(false),
- _ => Err(ParseBoolError { _priv: () }),
- }
- }
-}
-
-/// An error returned when parsing a `bool` using [`from_str`] fails
-///
-/// [`from_str`]: FromStr::from_str
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ParseBoolError {
- _priv: (),
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for ParseBoolError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- "provided string was not `true` or `false`".fmt(f)
- }
-}
-
-/*
-Section: Creating a string
-*/
-
-/// Errors which can occur when attempting to interpret a sequence of [`u8`]
-/// as a string.
-///
-/// As such, the `from_utf8` family of functions and methods for both [`String`]s
-/// and [`&str`]s make use of this error, for example.
-///
-/// [`String`]: ../../std/string/struct.String.html#method.from_utf8
-/// [`&str`]: from_utf8
-///
-/// # Examples
-///
-/// This error type’s methods can be used to create functionality
-/// similar to `String::from_utf8_lossy` without allocating heap memory:
-///
-/// ```
-/// fn from_utf8_lossy<F>(mut input: &[u8], mut push: F) where F: FnMut(&str) {
-/// loop {
-/// match std::str::from_utf8(input) {
-/// Ok(valid) => {
-/// push(valid);
-/// break
-/// }
-/// Err(error) => {
-/// let (valid, after_valid) = input.split_at(error.valid_up_to());
-/// unsafe {
-/// push(std::str::from_utf8_unchecked(valid))
-/// }
-/// push("\u{FFFD}");
-///
-/// if let Some(invalid_sequence_length) = error.error_len() {
-/// input = &after_valid[invalid_sequence_length..]
-/// } else {
-/// break
-/// }
-/// }
-/// }
-/// }
-/// }
-/// ```
-#[derive(Copy, Eq, PartialEq, Clone, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Utf8Error {
- valid_up_to: usize,
- error_len: Option<u8>,
-}
-
-impl Utf8Error {
- /// Returns the index in the given string up to which valid UTF-8 was
- /// verified.
- ///
- /// It is the maximum index such that `from_utf8(&input[..index])`
- /// would return `Ok(_)`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// use std::str;
- ///
- /// // some invalid bytes, in a vector
- /// let sparkle_heart = vec![0, 159, 146, 150];
- ///
- /// // std::str::from_utf8 returns a Utf8Error
- /// let error = str::from_utf8(&sparkle_heart).unwrap_err();
- ///
- /// // the second byte is invalid here
- /// assert_eq!(1, error.valid_up_to());
- /// ```
- #[stable(feature = "utf8_error", since = "1.5.0")]
- pub fn valid_up_to(&self) -> usize {
- self.valid_up_to
- }
-
- /// Provides more information about the failure:
- ///
- /// * `None`: the end of the input was reached unexpectedly.
- /// `self.valid_up_to()` is 1 to 3 bytes from the end of the input.
- /// If a byte stream (such as a file or a network socket) is being decoded incrementally,
- /// this could be a valid `char` whose UTF-8 byte sequence is spanning multiple chunks.
- ///
- /// * `Some(len)`: an unexpected byte was encountered.
- /// The length provided is that of the invalid byte sequence
- /// that starts at the index given by `valid_up_to()`.
- /// Decoding should resume after that sequence
- /// (after inserting a [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD]) in case of
- /// lossy decoding.
- ///
- /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
- #[stable(feature = "utf8_error_error_len", since = "1.20.0")]
- pub fn error_len(&self) -> Option<usize> {
- self.error_len.map(|len| len as usize)
- }
-}
-
-/// Converts a slice of bytes to a string slice.
-///
-/// A string slice ([`&str`]) is made of bytes ([`u8`]), and a byte slice
-/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts between
-/// the two. Not all byte slices are valid string slices, however: [`&str`] requires
-/// that it is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
-/// UTF-8, and then does the conversion.
-///
-/// [`&str`]: str
-/// [byteslice]: ../../std/primitive.slice.html
-///
-/// If you are sure that the byte slice is valid UTF-8, and you don't want to
-/// incur the overhead of the validity check, there is an unsafe version of
-/// this function, [`from_utf8_unchecked`][fromutf8u], which has the same
-/// behavior but skips the check.
-///
-/// [fromutf8u]: fn.from_utf8_unchecked.html
-///
-/// If you need a `String` instead of a `&str`, consider
-/// [`String::from_utf8`][string].
-///
-/// [string]: ../../std/string/struct.String.html#method.from_utf8
-///
-/// Because you can stack-allocate a `[u8; N]`, and you can take a
-/// [`&[u8]`][byteslice] of it, this function is one way to have a
-/// stack-allocated string. There is an example of this in the
-/// examples section below.
-///
-/// [byteslice]: ../../std/primitive.slice.html
-///
-/// # Errors
-///
-/// Returns `Err` if the slice is not UTF-8 with a description as to why the
-/// provided slice is not UTF-8.
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::str;
-///
-/// // some bytes, in a vector
-/// let sparkle_heart = vec![240, 159, 146, 150];
-///
-/// // We know these bytes are valid, so just use `unwrap()`.
-/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
-///
-/// assert_eq!("š", sparkle_heart);
-/// ```
-///
-/// Incorrect bytes:
-///
-/// ```
-/// use std::str;
-///
-/// // some invalid bytes, in a vector
-/// let sparkle_heart = vec![0, 159, 146, 150];
-///
-/// assert!(str::from_utf8(&sparkle_heart).is_err());
-/// ```
-///
-/// See the docs for [`Utf8Error`][error] for more details on the kinds of
-/// errors that can be returned.
-///
-/// [error]: struct.Utf8Error.html
-///
-/// A "stack allocated string":
-///
-/// ```
-/// use std::str;
-///
-/// // some bytes, in a stack-allocated array
-/// let sparkle_heart = [240, 159, 146, 150];
-///
-/// // We know these bytes are valid, so just use `unwrap()`.
-/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
-///
-/// assert_eq!("š", sparkle_heart);
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
- run_utf8_validation(v)?;
- // SAFETY: Just ran validation.
- Ok(unsafe { from_utf8_unchecked(v) })
-}
-
-/// Converts a mutable slice of bytes to a mutable string slice.
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::str;
-///
-/// // "Hello, Rust!" as a mutable vector
-/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
-///
-/// // As we know these bytes are valid, we can use `unwrap()`
-/// let outstr = str::from_utf8_mut(&mut hellorust).unwrap();
-///
-/// assert_eq!("Hello, Rust!", outstr);
-/// ```
-///
-/// Incorrect bytes:
-///
-/// ```
-/// use std::str;
-///
-/// // Some invalid bytes in a mutable vector
-/// let mut invalid = vec![128, 223];
-///
-/// assert!(str::from_utf8_mut(&mut invalid).is_err());
-/// ```
-/// See the docs for [`Utf8Error`][error] for more details on the kinds of
-/// errors that can be returned.
-///
-/// [error]: struct.Utf8Error.html
#[stable(feature = "str_mut_extras", since = "1.20.0")]
-pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
- run_utf8_validation(v)?;
- // SAFETY: Just ran validation.
- Ok(unsafe { from_utf8_unchecked_mut(v) })
-}
-
-/// Converts a slice of bytes to a string slice without checking
-/// that the string contains valid UTF-8.
-///
-/// See the safe version, [`from_utf8`][fromutf8], for more information.
-///
-/// [fromutf8]: fn.from_utf8.html
-///
-/// # Safety
-///
-/// This function is unsafe because it does not check that the bytes passed to
-/// it are valid UTF-8. If this constraint is violated, undefined behavior
-/// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
-///
-/// [`&str`]: str
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::str;
-///
-/// // some bytes, in a vector
-/// let sparkle_heart = vec![240, 159, 146, 150];
-///
-/// let sparkle_heart = unsafe {
-/// str::from_utf8_unchecked(&sparkle_heart)
-/// };
-///
-/// assert_eq!("š", sparkle_heart);
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")]
-#[allow(unused_attributes)]
-#[allow_internal_unstable(const_fn_transmute)]
-pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
- // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
- // Also relies on `&str` and `&[u8]` having the same layout.
- unsafe { mem::transmute(v) }
-}
-
-/// Converts a slice of bytes to a string slice without checking
-/// that the string contains valid UTF-8; mutable version.
-///
-/// See the immutable version, [`from_utf8_unchecked()`] for more information.
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::str;
-///
-/// let mut heart = vec![240, 159, 146, 150];
-/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
-///
-/// assert_eq!("š", heart);
-/// ```
-#[inline]
-#[stable(feature = "str_mut_extras", since = "1.20.0")]
-pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
- // SAFETY: the caller must guarantee that the bytes `v`
- // are valid UTF-8, thus the cast to `*mut str` is safe.
- // Also, the pointer dereference is safe because that pointer
- // comes from a reference which is guaranteed to be valid for writes.
- unsafe { &mut *(v as *mut [u8] as *mut str) }
-}
+pub use converts::{from_utf8_mut, from_utf8_unchecked_mut};
#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for Utf8Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- if let Some(error_len) = self.error_len {
- write!(
- f,
- "invalid utf-8 sequence of {} bytes from index {}",
- error_len, self.valid_up_to
- )
- } else {
- write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to)
- }
- }
-}
+pub use error::{ParseBoolError, Utf8Error};
-/*
-Section: Iterators
-*/
-
-/// An iterator over the [`char`]s of a string slice.
-///
-///
-/// This struct is created by the [`chars`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`char`]: prim@char
-/// [`chars`]: str::chars
-#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Chars<'a> {
- iter: slice::Iter<'a, u8>,
-}
+pub use traits::FromStr;
-/// Returns the initial codepoint accumulator for the first byte.
-/// The first byte is special, only want bottom 5 bits for width 2, 4 bits
-/// for width 3, and 3 bits for width 4.
-#[inline]
-fn utf8_first_byte(byte: u8, width: u32) -> u32 {
- (byte & (0x7F >> width)) as u32
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{Bytes, CharIndices, Chars, Lines, SplitWhitespace};
-/// Returns the value of `ch` updated with continuation byte `byte`.
-#[inline]
-fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 {
- (ch << 6) | (byte & CONT_MASK) as u32
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
+pub use iter::LinesAny;
-/// Checks whether the byte is a UTF-8 continuation byte (i.e., starts with the
-/// bits `10`).
-#[inline]
-fn utf8_is_cont_byte(byte: u8) -> bool {
- (byte & !CONT_MASK) == TAG_CONT_U8
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{RSplit, RSplitTerminator, Split, SplitTerminator};
-#[inline]
-fn unwrap_or_0(opt: Option<&u8>) -> u8 {
- match opt {
- Some(&byte) => byte,
- None => 0,
- }
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use iter::{RSplitN, SplitN};
-/// Reads the next code point out of a byte iterator (assuming a
-/// UTF-8-like encoding).
+#[stable(feature = "str_matches", since = "1.2.0")]
+pub use iter::{Matches, RMatches};
+
+#[stable(feature = "str_match_indices", since = "1.5.0")]
+pub use iter::{MatchIndices, RMatchIndices};
+
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+pub use iter::EncodeUtf16;
+
+#[stable(feature = "str_escape", since = "1.34.0")]
+pub use iter::{EscapeDebug, EscapeDefault, EscapeUnicode};
+
+#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
+pub use iter::SplitAsciiWhitespace;
+
+#[unstable(feature = "split_inclusive", issue = "72360")]
+use iter::SplitInclusive;
+
#[unstable(feature = "str_internals", issue = "none")]
-#[inline]
-pub fn next_code_point<'a, I: Iterator<Item = &'a u8>>(bytes: &mut I) -> Option<u32> {
- // Decode UTF-8
- let x = *bytes.next()?;
- if x < 128 {
- return Some(x as u32);
- }
+pub use validations::next_code_point;
- // Multibyte case follows
- // Decode from a byte combination out of: [[[x y] z] w]
- // NOTE: Performance is sensitive to the exact formulation here
- let init = utf8_first_byte(x, 2);
- let y = unwrap_or_0(bytes.next());
- let mut ch = utf8_acc_cont_byte(init, y);
- if x >= 0xE0 {
- // [[x y z] w] case
- // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
- let z = unwrap_or_0(bytes.next());
- let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
- ch = init << 12 | y_z;
- if x >= 0xF0 {
- // [x y z w] case
- // use only the lower 3 bits of `init`
- let w = unwrap_or_0(bytes.next());
- ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
- }
- }
+use iter::MatchIndicesInternal;
+use iter::SplitInternal;
+use iter::{MatchesInternal, SplitNInternal};
- Some(ch)
-}
-
-/// Reads the last code point out of a byte iterator (assuming a
-/// UTF-8-like encoding).
-#[inline]
-fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option<u32>
-where
- I: DoubleEndedIterator<Item = &'a u8>,
-{
- // Decode UTF-8
- let w = match *bytes.next_back()? {
- next_byte if next_byte < 128 => return Some(next_byte as u32),
- back_byte => back_byte,
- };
-
- // Multibyte case follows
- // Decode from a byte combination out of: [x [y [z w]]]
- let mut ch;
- let z = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte(z, 2);
- if utf8_is_cont_byte(z) {
- let y = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte(y, 3);
- if utf8_is_cont_byte(y) {
- let x = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte(x, 4);
- ch = utf8_acc_cont_byte(ch, y);
- }
- ch = utf8_acc_cont_byte(ch, z);
- }
- ch = utf8_acc_cont_byte(ch, w);
-
- Some(ch)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for Chars<'a> {
- type Item = char;
-
- #[inline]
- fn next(&mut self) -> Option<char> {
- next_code_point(&mut self.iter).map(|ch| {
- // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
- unsafe { char::from_u32_unchecked(ch) }
- })
- }
-
- #[inline]
- fn count(self) -> usize {
- // length in `char` is equal to the number of non-continuation bytes
- let bytes_len = self.iter.len();
- let mut cont_bytes = 0;
- for &byte in self.iter {
- cont_bytes += utf8_is_cont_byte(byte) as usize;
- }
- bytes_len - cont_bytes
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let len = self.iter.len();
- // `(len + 3)` can't overflow, because we know that the `slice::Iter`
- // belongs to a slice in memory which has a maximum length of
- // `isize::MAX` (that's well below `usize::MAX`).
- ((len + 3) / 4, Some(len))
- }
-
- #[inline]
- fn last(mut self) -> Option<char> {
- // No need to go through the entire string.
- self.next_back()
- }
-}
-
-#[stable(feature = "chars_debug_impl", since = "1.38.0")]
-impl fmt::Debug for Chars<'_> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Chars(")?;
- f.debug_list().entries(self.clone()).finish()?;
- write!(f, ")")?;
- Ok(())
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> DoubleEndedIterator for Chars<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<char> {
- next_code_point_reverse(&mut self.iter).map(|ch| {
- // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
- unsafe { char::from_u32_unchecked(ch) }
- })
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for Chars<'_> {}
-
-impl<'a> Chars<'a> {
- /// Views the underlying data as a subslice of the original data.
- ///
- /// This has the same lifetime as the original slice, and so the
- /// iterator can continue to be used while this exists.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut chars = "abc".chars();
- ///
- /// assert_eq!(chars.as_str(), "abc");
- /// chars.next();
- /// assert_eq!(chars.as_str(), "bc");
- /// chars.next();
- /// chars.next();
- /// assert_eq!(chars.as_str(), "");
- /// ```
- #[stable(feature = "iter_to_slice", since = "1.4.0")]
- #[inline]
- pub fn as_str(&self) -> &'a str {
- // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
- unsafe { from_utf8_unchecked(self.iter.as_slice()) }
- }
-}
-
-/// An iterator over the [`char`]s of a string slice, and their positions.
-///
-/// This struct is created by the [`char_indices`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`char`]: prim@char
-/// [`char_indices`]: str::char_indices
-#[derive(Clone, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct CharIndices<'a> {
- front_offset: usize,
- iter: Chars<'a>,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for CharIndices<'a> {
- type Item = (usize, char);
-
- #[inline]
- fn next(&mut self) -> Option<(usize, char)> {
- let pre_len = self.iter.iter.len();
- match self.iter.next() {
- None => None,
- Some(ch) => {
- let index = self.front_offset;
- let len = self.iter.iter.len();
- self.front_offset += pre_len - len;
- Some((index, ch))
- }
- }
- }
-
- #[inline]
- fn count(self) -> usize {
- self.iter.count()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- #[inline]
- fn last(mut self) -> Option<(usize, char)> {
- // No need to go through the entire string.
- self.next_back()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> DoubleEndedIterator for CharIndices<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<(usize, char)> {
- self.iter.next_back().map(|ch| {
- let index = self.front_offset + self.iter.iter.len();
- (index, ch)
- })
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for CharIndices<'_> {}
-
-impl<'a> CharIndices<'a> {
- /// Views the underlying data as a subslice of the original data.
- ///
- /// This has the same lifetime as the original slice, and so the
- /// iterator can continue to be used while this exists.
- #[stable(feature = "iter_to_slice", since = "1.4.0")]
- #[inline]
- pub fn as_str(&self) -> &'a str {
- self.iter.as_str()
- }
-}
-
-/// An iterator over the bytes of a string slice.
-///
-/// This struct is created by the [`bytes`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`bytes`]: str::bytes
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone, Debug)]
-pub struct Bytes<'a>(Copied<slice::Iter<'a, u8>>);
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Iterator for Bytes<'_> {
- type Item = u8;
-
- #[inline]
- fn next(&mut self) -> Option<u8> {
- self.0.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-
- #[inline]
- fn count(self) -> usize {
- self.0.count()
- }
-
- #[inline]
- fn last(self) -> Option<Self::Item> {
- self.0.last()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- self.0.nth(n)
- }
-
- #[inline]
- fn all<F>(&mut self, f: F) -> bool
- where
- F: FnMut(Self::Item) -> bool,
- {
- self.0.all(f)
- }
-
- #[inline]
- fn any<F>(&mut self, f: F) -> bool
- where
- F: FnMut(Self::Item) -> bool,
- {
- self.0.any(f)
- }
-
- #[inline]
- fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
- where
- P: FnMut(&Self::Item) -> bool,
- {
- self.0.find(predicate)
- }
-
- #[inline]
- fn position<P>(&mut self, predicate: P) -> Option<usize>
- where
- P: FnMut(Self::Item) -> bool,
- {
- self.0.position(predicate)
- }
-
- #[inline]
- fn rposition<P>(&mut self, predicate: P) -> Option<usize>
- where
- P: FnMut(Self::Item) -> bool,
- {
- self.0.rposition(predicate)
- }
-
- #[inline]
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
- // SAFETY: the caller must uphold the safety contract
- // for `Iterator::get_unchecked`.
- unsafe { self.0.__iterator_get_unchecked(idx) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl DoubleEndedIterator for Bytes<'_> {
- #[inline]
- fn next_back(&mut self) -> Option<u8> {
- self.0.next_back()
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- self.0.nth_back(n)
- }
-
- #[inline]
- fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
- where
- P: FnMut(&Self::Item) -> bool,
- {
- self.0.rfind(predicate)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ExactSizeIterator for Bytes<'_> {
- #[inline]
- fn len(&self) -> usize {
- self.0.len()
- }
-
- #[inline]
- fn is_empty(&self) -> bool {
- self.0.is_empty()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for Bytes<'_> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl TrustedLen for Bytes<'_> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl TrustedRandomAccess for Bytes<'_> {
- fn may_have_side_effect() -> bool {
- false
- }
-}
-
-/// This macro generates a Clone impl for string pattern API
-/// wrapper types of the form X<'a, P>
-macro_rules! derive_pattern_clone {
- (clone $t:ident with |$s:ident| $e:expr) => {
- impl<'a, P> Clone for $t<'a, P>
- where
- P: Pattern<'a, Searcher: Clone>,
- {
- fn clone(&self) -> Self {
- let $s = self;
- $e
- }
- }
- };
-}
-
-/// This macro generates two public iterator structs
-/// wrapping a private internal one that makes use of the `Pattern` API.
-///
-/// For all patterns `P: Pattern<'a>` the following items will be
-/// generated (generics omitted):
-///
-/// struct $forward_iterator($internal_iterator);
-/// struct $reverse_iterator($internal_iterator);
-///
-/// impl Iterator for $forward_iterator
-/// { /* internal ends up calling Searcher::next_match() */ }
-///
-/// impl DoubleEndedIterator for $forward_iterator
-/// where P::Searcher: DoubleEndedSearcher
-/// { /* internal ends up calling Searcher::next_match_back() */ }
-///
-/// impl Iterator for $reverse_iterator
-/// where P::Searcher: ReverseSearcher
-/// { /* internal ends up calling Searcher::next_match_back() */ }
-///
-/// impl DoubleEndedIterator for $reverse_iterator
-/// where P::Searcher: DoubleEndedSearcher
-/// { /* internal ends up calling Searcher::next_match() */ }
-///
-/// The internal one is defined outside the macro, and has almost the same
-/// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
-/// `pattern::ReverseSearcher` for both forward and reverse iteration.
-///
-/// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
-/// `Pattern` might not return the same elements, so actually implementing
-/// `DoubleEndedIterator` for it would be incorrect.
-/// (See the docs in `str::pattern` for more details)
-///
-/// However, the internal struct still represents a single ended iterator from
-/// either end, and depending on pattern is also a valid double ended iterator,
-/// so the two wrapper structs implement `Iterator`
-/// and `DoubleEndedIterator` depending on the concrete pattern type, leading
-/// to the complex impls seen above.
-macro_rules! generate_pattern_iterators {
- {
- // Forward iterator
- forward:
- $(#[$forward_iterator_attribute:meta])*
- struct $forward_iterator:ident;
-
- // Reverse iterator
- reverse:
- $(#[$reverse_iterator_attribute:meta])*
- struct $reverse_iterator:ident;
-
- // Stability of all generated items
- stability:
- $(#[$common_stability_attribute:meta])*
-
- // Internal almost-iterator that is being delegated to
- internal:
- $internal_iterator:ident yielding ($iterty:ty);
-
- // Kind of delegation - either single ended or double ended
- delegate $($t:tt)*
- } => {
- $(#[$forward_iterator_attribute])*
- $(#[$common_stability_attribute])*
- pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
-
- $(#[$common_stability_attribute])*
- impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: fmt::Debug>,
- {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple(stringify!($forward_iterator))
- .field(&self.0)
- .finish()
- }
- }
-
- $(#[$common_stability_attribute])*
- impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
- type Item = $iterty;
-
- #[inline]
- fn next(&mut self) -> Option<$iterty> {
- self.0.next()
- }
- }
-
- $(#[$common_stability_attribute])*
- impl<'a, P> Clone for $forward_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: Clone>,
- {
- fn clone(&self) -> Self {
- $forward_iterator(self.0.clone())
- }
- }
-
- $(#[$reverse_iterator_attribute])*
- $(#[$common_stability_attribute])*
- pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
-
- $(#[$common_stability_attribute])*
- impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: fmt::Debug>,
- {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple(stringify!($reverse_iterator))
- .field(&self.0)
- .finish()
- }
- }
-
- $(#[$common_stability_attribute])*
- impl<'a, P> Iterator for $reverse_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
- {
- type Item = $iterty;
-
- #[inline]
- fn next(&mut self) -> Option<$iterty> {
- self.0.next_back()
- }
- }
-
- $(#[$common_stability_attribute])*
- impl<'a, P> Clone for $reverse_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: Clone>,
- {
- fn clone(&self) -> Self {
- $reverse_iterator(self.0.clone())
- }
- }
-
- #[stable(feature = "fused", since = "1.26.0")]
- impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
-
- #[stable(feature = "fused", since = "1.26.0")]
- impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
- {}
-
- generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
- $forward_iterator,
- $reverse_iterator, $iterty);
- };
- {
- double ended; with $(#[$common_stability_attribute:meta])*,
- $forward_iterator:ident,
- $reverse_iterator:ident, $iterty:ty
- } => {
- $(#[$common_stability_attribute])*
- impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
- {
- #[inline]
- fn next_back(&mut self) -> Option<$iterty> {
- self.0.next_back()
- }
- }
-
- $(#[$common_stability_attribute])*
- impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
- where
- P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
- {
- #[inline]
- fn next_back(&mut self) -> Option<$iterty> {
- self.0.next()
- }
- }
- };
- {
- single ended; with $(#[$common_stability_attribute:meta])*,
- $forward_iterator:ident,
- $reverse_iterator:ident, $iterty:ty
- } => {}
-}
-
-derive_pattern_clone! {
- clone SplitInternal
- with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
-}
-
-struct SplitInternal<'a, P: Pattern<'a>> {
- start: usize,
- end: usize,
- matcher: P::Searcher,
- allow_trailing_empty: bool,
- finished: bool,
-}
-
-impl<'a, P> fmt::Debug for SplitInternal<'a, P>
-where
- P: Pattern<'a, Searcher: fmt::Debug>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitInternal")
- .field("start", &self.start)
- .field("end", &self.end)
- .field("matcher", &self.matcher)
- .field("allow_trailing_empty", &self.allow_trailing_empty)
- .field("finished", &self.finished)
- .finish()
- }
-}
-
-impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
- #[inline]
- fn get_end(&mut self) -> Option<&'a str> {
- if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
- self.finished = true;
- // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
- unsafe {
- let string = self.matcher.haystack().get_unchecked(self.start..self.end);
- Some(string)
- }
- } else {
- None
- }
- }
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- if self.finished {
- return None;
- }
-
- let haystack = self.matcher.haystack();
- match self.matcher.next_match() {
- // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
- Some((a, b)) => unsafe {
- let elt = haystack.get_unchecked(self.start..a);
- self.start = b;
- Some(elt)
- },
- None => self.get_end(),
- }
- }
-
- #[inline]
- fn next_inclusive(&mut self) -> Option<&'a str> {
- if self.finished {
- return None;
- }
-
- let haystack = self.matcher.haystack();
- match self.matcher.next_match() {
- // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
- // and self.start is either the start of the original string,
- // or `b` was assigned to it, so it also lies on unicode boundary.
- Some((_, b)) => unsafe {
- let elt = haystack.get_unchecked(self.start..b);
- self.start = b;
- Some(elt)
- },
- None => self.get_end(),
- }
- }
-
- #[inline]
- fn next_back(&mut self) -> Option<&'a str>
- where
- P::Searcher: ReverseSearcher<'a>,
- {
- if self.finished {
- return None;
- }
-
- if !self.allow_trailing_empty {
- self.allow_trailing_empty = true;
- match self.next_back() {
- Some(elt) if !elt.is_empty() => return Some(elt),
- _ => {
- if self.finished {
- return None;
- }
- }
- }
- }
-
- let haystack = self.matcher.haystack();
- match self.matcher.next_match_back() {
- // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
- Some((a, b)) => unsafe {
- let elt = haystack.get_unchecked(b..self.end);
- self.end = a;
- Some(elt)
- },
- // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
- None => unsafe {
- self.finished = true;
- Some(haystack.get_unchecked(self.start..self.end))
- },
- }
- }
-
- #[inline]
- fn next_back_inclusive(&mut self) -> Option<&'a str>
- where
- P::Searcher: ReverseSearcher<'a>,
- {
- if self.finished {
- return None;
- }
-
- if !self.allow_trailing_empty {
- self.allow_trailing_empty = true;
- match self.next_back_inclusive() {
- Some(elt) if !elt.is_empty() => return Some(elt),
- _ => {
- if self.finished {
- return None;
- }
- }
- }
- }
-
- let haystack = self.matcher.haystack();
- match self.matcher.next_match_back() {
- // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
- // and self.end is either the end of the original string,
- // or `b` was assigned to it, so it also lies on unicode boundary.
- Some((_, b)) => unsafe {
- let elt = haystack.get_unchecked(b..self.end);
- self.end = b;
- Some(elt)
- },
- // SAFETY: self.start is either the start of the original string,
- // or start of a substring that represents the part of the string that hasn't
- // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
- // self.end is either the end of the original string,
- // or `b` was assigned to it, so it also lies on unicode boundary.
- None => unsafe {
- self.finished = true;
- Some(haystack.get_unchecked(self.start..self.end))
- },
- }
- }
-}
-
-generate_pattern_iterators! {
- forward:
- /// Created with the method [`split`].
- ///
- /// [`split`]: str::split
- struct Split;
- reverse:
- /// Created with the method [`rsplit`].
- ///
- /// [`rsplit`]: str::rsplit
- struct RSplit;
- stability:
- #[stable(feature = "rust1", since = "1.0.0")]
- internal:
- SplitInternal yielding (&'a str);
- delegate double ended;
-}
-
-generate_pattern_iterators! {
- forward:
- /// Created with the method [`split_terminator`].
- ///
- /// [`split_terminator`]: str::split_terminator
- struct SplitTerminator;
- reverse:
- /// Created with the method [`rsplit_terminator`].
- ///
- /// [`rsplit_terminator`]: str::rsplit_terminator
- struct RSplitTerminator;
- stability:
- #[stable(feature = "rust1", since = "1.0.0")]
- internal:
- SplitInternal yielding (&'a str);
- delegate double ended;
-}
-
-derive_pattern_clone! {
- clone SplitNInternal
- with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
-}
-
-struct SplitNInternal<'a, P: Pattern<'a>> {
- iter: SplitInternal<'a, P>,
- /// The number of splits remaining
- count: usize,
-}
-
-impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
-where
- P: Pattern<'a, Searcher: fmt::Debug>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitNInternal")
- .field("iter", &self.iter)
- .field("count", &self.count)
- .finish()
- }
-}
-
-impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- match self.count {
- 0 => None,
- 1 => {
- self.count = 0;
- self.iter.get_end()
- }
- _ => {
- self.count -= 1;
- self.iter.next()
- }
- }
- }
-
- #[inline]
- fn next_back(&mut self) -> Option<&'a str>
- where
- P::Searcher: ReverseSearcher<'a>,
- {
- match self.count {
- 0 => None,
- 1 => {
- self.count = 0;
- self.iter.get_end()
- }
- _ => {
- self.count -= 1;
- self.iter.next_back()
- }
- }
- }
-}
-
-generate_pattern_iterators! {
- forward:
- /// Created with the method [`splitn`].
- ///
- /// [`splitn`]: str::splitn
- struct SplitN;
- reverse:
- /// Created with the method [`rsplitn`].
- ///
- /// [`rsplitn`]: str::rsplitn
- struct RSplitN;
- stability:
- #[stable(feature = "rust1", since = "1.0.0")]
- internal:
- SplitNInternal yielding (&'a str);
- delegate single ended;
-}
-
-derive_pattern_clone! {
- clone MatchIndicesInternal
- with |s| MatchIndicesInternal(s.0.clone())
-}
-
-struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher);
-
-impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
-where
- P: Pattern<'a, Searcher: fmt::Debug>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
- }
-}
-
-impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
- #[inline]
- fn next(&mut self) -> Option<(usize, &'a str)> {
- self.0
- .next_match()
- // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
- .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
- }
-
- #[inline]
- fn next_back(&mut self) -> Option<(usize, &'a str)>
- where
- P::Searcher: ReverseSearcher<'a>,
- {
- self.0
- .next_match_back()
- // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
- .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
- }
-}
-
-generate_pattern_iterators! {
- forward:
- /// Created with the method [`match_indices`].
- ///
- /// [`match_indices`]: str::match_indices
- struct MatchIndices;
- reverse:
- /// Created with the method [`rmatch_indices`].
- ///
- /// [`rmatch_indices`]: str::rmatch_indices
- struct RMatchIndices;
- stability:
- #[stable(feature = "str_match_indices", since = "1.5.0")]
- internal:
- MatchIndicesInternal yielding ((usize, &'a str));
- delegate double ended;
-}
-
-derive_pattern_clone! {
- clone MatchesInternal
- with |s| MatchesInternal(s.0.clone())
-}
-
-struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher);
-
-impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
-where
- P: Pattern<'a, Searcher: fmt::Debug>,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("MatchesInternal").field(&self.0).finish()
- }
-}
-
-impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
- self.0.next_match().map(|(a, b)| unsafe {
- // Indices are known to be on utf8 boundaries
- self.0.haystack().get_unchecked(a..b)
- })
- }
-
- #[inline]
- fn next_back(&mut self) -> Option<&'a str>
- where
- P::Searcher: ReverseSearcher<'a>,
- {
- // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
- self.0.next_match_back().map(|(a, b)| unsafe {
- // Indices are known to be on utf8 boundaries
- self.0.haystack().get_unchecked(a..b)
- })
- }
-}
-
-generate_pattern_iterators! {
- forward:
- /// Created with the method [`matches`].
- ///
- /// [`matches`]: str::matches
- struct Matches;
- reverse:
- /// Created with the method [`rmatches`].
- ///
- /// [`rmatches`]: str::rmatches
- struct RMatches;
- stability:
- #[stable(feature = "str_matches", since = "1.2.0")]
- internal:
- MatchesInternal yielding (&'a str);
- delegate double ended;
-}
-
-/// An iterator over the lines of a string, as string slices.
-///
-/// This struct is created with the [`lines`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`lines`]: str::lines
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone, Debug)]
-pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>);
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for Lines<'a> {
- type Item = &'a str;
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- self.0.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-
- #[inline]
- fn last(mut self) -> Option<&'a str> {
- self.next_back()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> DoubleEndedIterator for Lines<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a str> {
- self.0.next_back()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for Lines<'_> {}
-
-/// Created with the method [`lines_any`].
-///
-/// [`lines_any`]: str::lines_any
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
-#[derive(Clone, Debug)]
-#[allow(deprecated)]
-pub struct LinesAny<'a>(Lines<'a>);
-
-impl_fn_for_zst! {
- /// A nameable, cloneable fn type
- #[derive(Clone)]
- struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> &'a str {
- let l = line.len();
- if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
- else { line }
- };
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a> Iterator for LinesAny<'a> {
- type Item = &'a str;
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- self.0.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a> DoubleEndedIterator for LinesAny<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a str> {
- self.0.next_back()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-#[allow(deprecated)]
-impl FusedIterator for LinesAny<'_> {}
-
-/*
-Section: UTF-8 validation
-*/
-
-// use truncation to fit u64 into usize
-const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
-
-/// Returns `true` if any byte in the word `x` is nonascii (>= 128).
-#[inline]
-fn contains_nonascii(x: usize) -> bool {
- (x & NONASCII_MASK) != 0
-}
-
-/// Walks through `v` checking that it's a valid UTF-8 sequence,
-/// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`.
-#[inline(always)]
-fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
- let mut index = 0;
- let len = v.len();
-
- let usize_bytes = mem::size_of::<usize>();
- let ascii_block_size = 2 * usize_bytes;
- let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 };
- let align = v.as_ptr().align_offset(usize_bytes);
-
- while index < len {
- let old_offset = index;
- macro_rules! err {
- ($error_len: expr) => {
- return Err(Utf8Error { valid_up_to: old_offset, error_len: $error_len });
- };
- }
-
- macro_rules! next {
- () => {{
- index += 1;
- // we needed data, but there was none: error!
- if index >= len {
- err!(None)
- }
- v[index]
- }};
- }
-
- let first = v[index];
- if first >= 128 {
- let w = UTF8_CHAR_WIDTH[first as usize];
- // 2-byte encoding is for codepoints \u{0080} to \u{07ff}
- // first C2 80 last DF BF
- // 3-byte encoding is for codepoints \u{0800} to \u{ffff}
- // first E0 A0 80 last EF BF BF
- // excluding surrogates codepoints \u{d800} to \u{dfff}
- // ED A0 80 to ED BF BF
- // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
- // first F0 90 80 80 last F4 8F BF BF
- //
- // Use the UTF-8 syntax from the RFC
- //
- // https://tools.ietf.org/html/rfc3629
- // UTF8-1 = %x00-7F
- // UTF8-2 = %xC2-DF UTF8-tail
- // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
- // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
- // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
- // %xF4 %x80-8F 2( UTF8-tail )
- match w {
- 2 => {
- if next!() & !CONT_MASK != TAG_CONT_U8 {
- err!(Some(1))
- }
- }
- 3 => {
- match (first, next!()) {
- (0xE0, 0xA0..=0xBF)
- | (0xE1..=0xEC, 0x80..=0xBF)
- | (0xED, 0x80..=0x9F)
- | (0xEE..=0xEF, 0x80..=0xBF) => {}
- _ => err!(Some(1)),
- }
- if next!() & !CONT_MASK != TAG_CONT_U8 {
- err!(Some(2))
- }
- }
- 4 => {
- match (first, next!()) {
- (0xF0, 0x90..=0xBF) | (0xF1..=0xF3, 0x80..=0xBF) | (0xF4, 0x80..=0x8F) => {}
- _ => err!(Some(1)),
- }
- if next!() & !CONT_MASK != TAG_CONT_U8 {
- err!(Some(2))
- }
- if next!() & !CONT_MASK != TAG_CONT_U8 {
- err!(Some(3))
- }
- }
- _ => err!(Some(1)),
- }
- index += 1;
- } else {
- // Ascii case, try to skip forward quickly.
- // When the pointer is aligned, read 2 words of data per iteration
- // until we find a word containing a non-ascii byte.
- if align != usize::MAX && align.wrapping_sub(index) % usize_bytes == 0 {
- let ptr = v.as_ptr();
- while index < blocks_end {
- // SAFETY: since `align - index` and `ascii_block_size` are
- // multiples of `usize_bytes`, `block = ptr.add(index)` is
- // always aligned with a `usize` so it's safe to dereference
- // both `block` and `block.offset(1)`.
- unsafe {
- let block = ptr.add(index) as *const usize;
- // break if there is a nonascii byte
- let zu = contains_nonascii(*block);
- let zv = contains_nonascii(*block.offset(1));
- if zu | zv {
- break;
- }
- }
- index += ascii_block_size;
- }
- // step from the point where the wordwise loop stopped
- while index < len && v[index] < 128 {
- index += 1;
- }
- } else {
- index += 1;
- }
- }
- }
-
- Ok(())
-}
-
-// https://tools.ietf.org/html/rfc3629
-static UTF8_CHAR_WIDTH: [u8; 256] = [
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, // 0x1F
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, // 0x3F
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, // 0x5F
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, // 0x7F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, // 0x9F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, // 0xBF
- 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, // 0xDF
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF
- 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF
-];
-
-/// Given a first byte, determines how many bytes are in this UTF-8 character.
-#[unstable(feature = "str_internals", issue = "none")]
-#[inline]
-pub fn utf8_char_width(b: u8) -> usize {
- UTF8_CHAR_WIDTH[b as usize] as usize
-}
-
-/// Mask of the value bits of a continuation byte.
-const CONT_MASK: u8 = 0b0011_1111;
-/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte.
-const TAG_CONT_U8: u8 = 0b1000_0000;
-
-/*
-Section: Trait implementations
-*/
-
-mod traits {
- use crate::cmp::Ordering;
- use crate::ops;
- use crate::ptr;
- use crate::slice::SliceIndex;
-
- /// Implements ordering of strings.
- ///
- /// Strings are ordered lexicographically by their byte values. This orders Unicode code
- /// points based on their positions in the code charts. This is not necessarily the same as
- /// "alphabetical" order, which varies by language and locale. Sorting strings according to
- /// culturally-accepted standards requires locale-specific data that is outside the scope of
- /// the `str` type.
- #[stable(feature = "rust1", since = "1.0.0")]
- impl Ord for str {
- #[inline]
- fn cmp(&self, other: &str) -> Ordering {
- self.as_bytes().cmp(other.as_bytes())
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl PartialEq for str {
- #[inline]
- fn eq(&self, other: &str) -> bool {
- self.as_bytes() == other.as_bytes()
- }
- #[inline]
- fn ne(&self, other: &str) -> bool {
- !(*self).eq(other)
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl Eq for str {}
-
- /// Implements comparison operations on strings.
- ///
- /// Strings are compared lexicographically by their byte values. This compares Unicode code
- /// points based on their positions in the code charts. This is not necessarily the same as
- /// "alphabetical" order, which varies by language and locale. Comparing strings according to
- /// culturally-accepted standards requires locale-specific data that is outside the scope of
- /// the `str` type.
- #[stable(feature = "rust1", since = "1.0.0")]
- impl PartialOrd for str {
- #[inline]
- fn partial_cmp(&self, other: &str) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<I> ops::Index<I> for str
- where
- I: SliceIndex<str>,
- {
- type Output = I::Output;
-
- #[inline]
- fn index(&self, index: I) -> &I::Output {
- index.index(self)
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<I> ops::IndexMut<I> for str
- where
- I: SliceIndex<str>,
- {
- #[inline]
- fn index_mut(&mut self, index: I) -> &mut I::Output {
- index.index_mut(self)
- }
- }
-
- #[inline(never)]
- #[cold]
- #[track_caller]
- fn str_index_overflow_fail() -> ! {
- panic!("attempted to index str up to maximum usize");
- }
-
- /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
- ///
- /// Returns a slice of the whole string, i.e., returns `&self` or `&mut
- /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
- /// other indexing operations, this can never panic.
- ///
- /// This operation is `O(1)`.
- ///
- /// Prior to 1.20.0, these indexing operations were still supported by
- /// direct implementation of `Index` and `IndexMut`.
- ///
- /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- unsafe impl SliceIndex<str> for ops::RangeFull {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- Some(slice)
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- Some(slice)
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- slice
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- slice
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- slice
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- slice
- }
- }
-
- /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
- /// self[begin .. end]`.
- ///
- /// Returns a slice of the given string from the byte range
- /// [`begin`, `end`).
- ///
- /// This operation is `O(1)`.
- ///
- /// Prior to 1.20.0, these indexing operations were still supported by
- /// direct implementation of `Index` and `IndexMut`.
- ///
- /// # Panics
- ///
- /// Panics if `begin` or `end` does not point to the starting byte offset of
- /// a character (as defined by `is_char_boundary`), if `begin > end`, or if
- /// `end > len`.
- ///
- /// # Examples
- ///
- /// ```
- /// let s = "Löwe čč Léopard";
- /// assert_eq!(&s[0 .. 1], "L");
- ///
- /// assert_eq!(&s[1 .. 9], "öwe č");
- ///
- /// // these will panic:
- /// // byte 2 lies within `ö`:
- /// // &s[2 ..3];
- ///
- /// // byte 8 lies within `č`
- /// // &s[1 .. 8];
- ///
- /// // byte 100 is outside the string
- /// // &s[3 .. 100];
- /// ```
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- unsafe impl SliceIndex<str> for ops::Range<usize> {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- if self.start <= self.end
- && slice.is_char_boundary(self.start)
- && slice.is_char_boundary(self.end)
- {
- // SAFETY: just checked that `start` and `end` are on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- // We also checked char boundaries, so this is valid UTF-8.
- Some(unsafe { &*self.get_unchecked(slice) })
- } else {
- None
- }
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- if self.start <= self.end
- && slice.is_char_boundary(self.start)
- && slice.is_char_boundary(self.end)
- {
- // SAFETY: just checked that `start` and `end` are on a char boundary.
- // We know the pointer is unique because we got it from `slice`.
- Some(unsafe { &mut *self.get_unchecked_mut(slice) })
- } else {
- None
- }
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- let slice = slice as *const [u8];
- // SAFETY: the caller guarantees that `self` is in bounds of `slice`
- // which satisfies all the conditions for `add`.
- let ptr = unsafe { slice.as_ptr().add(self.start) };
- let len = self.end - self.start;
- ptr::slice_from_raw_parts(ptr, len) as *const str
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- let slice = slice as *mut [u8];
- // SAFETY: see comments for `get_unchecked`.
- let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
- let len = self.end - self.start;
- ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- let (start, end) = (self.start, self.end);
- match self.get(slice) {
- Some(s) => s,
- None => super::slice_error_fail(slice, start, end),
- }
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- // is_char_boundary checks that the index is in [0, .len()]
- // cannot reuse `get` as above, because of NLL trouble
- if self.start <= self.end
- && slice.is_char_boundary(self.start)
- && slice.is_char_boundary(self.end)
- {
- // SAFETY: just checked that `start` and `end` are on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- unsafe { &mut *self.get_unchecked_mut(slice) }
- } else {
- super::slice_error_fail(slice, self.start, self.end)
- }
- }
- }
-
- /// Implements substring slicing with syntax `&self[.. end]` or `&mut
- /// self[.. end]`.
- ///
- /// Returns a slice of the given string from the byte range [`0`, `end`).
- /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
- ///
- /// This operation is `O(1)`.
- ///
- /// Prior to 1.20.0, these indexing operations were still supported by
- /// direct implementation of `Index` and `IndexMut`.
- ///
- /// # Panics
- ///
- /// Panics if `end` does not point to the starting byte offset of a
- /// character (as defined by `is_char_boundary`), or if `end > len`.
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- if slice.is_char_boundary(self.end) {
- // SAFETY: just checked that `end` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- Some(unsafe { &*self.get_unchecked(slice) })
- } else {
- None
- }
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- if slice.is_char_boundary(self.end) {
- // SAFETY: just checked that `end` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- Some(unsafe { &mut *self.get_unchecked_mut(slice) })
- } else {
- None
- }
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- let slice = slice as *const [u8];
- let ptr = slice.as_ptr();
- ptr::slice_from_raw_parts(ptr, self.end) as *const str
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- let slice = slice as *mut [u8];
- let ptr = slice.as_mut_ptr();
- ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- let end = self.end;
- match self.get(slice) {
- Some(s) => s,
- None => super::slice_error_fail(slice, 0, end),
- }
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- if slice.is_char_boundary(self.end) {
- // SAFETY: just checked that `end` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- unsafe { &mut *self.get_unchecked_mut(slice) }
- } else {
- super::slice_error_fail(slice, 0, self.end)
- }
- }
- }
-
- /// Implements substring slicing with syntax `&self[begin ..]` or `&mut
- /// self[begin ..]`.
- ///
- /// Returns a slice of the given string from the byte range [`begin`,
- /// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin ..
- /// len]`.
- ///
- /// This operation is `O(1)`.
- ///
- /// Prior to 1.20.0, these indexing operations were still supported by
- /// direct implementation of `Index` and `IndexMut`.
- ///
- /// # Panics
- ///
- /// Panics if `begin` does not point to the starting byte offset of
- /// a character (as defined by `is_char_boundary`), or if `begin > len`.
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- if slice.is_char_boundary(self.start) {
- // SAFETY: just checked that `start` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- Some(unsafe { &*self.get_unchecked(slice) })
- } else {
- None
- }
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- if slice.is_char_boundary(self.start) {
- // SAFETY: just checked that `start` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- Some(unsafe { &mut *self.get_unchecked_mut(slice) })
- } else {
- None
- }
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- let slice = slice as *const [u8];
- // SAFETY: the caller guarantees that `self` is in bounds of `slice`
- // which satisfies all the conditions for `add`.
- let ptr = unsafe { slice.as_ptr().add(self.start) };
- let len = slice.len() - self.start;
- ptr::slice_from_raw_parts(ptr, len) as *const str
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- let slice = slice as *mut [u8];
- // SAFETY: identical to `get_unchecked`.
- let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
- let len = slice.len() - self.start;
- ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- let (start, end) = (self.start, slice.len());
- match self.get(slice) {
- Some(s) => s,
- None => super::slice_error_fail(slice, start, end),
- }
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- if slice.is_char_boundary(self.start) {
- // SAFETY: just checked that `start` is on a char boundary,
- // and we are passing in a safe reference, so the return value will also be one.
- unsafe { &mut *self.get_unchecked_mut(slice) }
- } else {
- super::slice_error_fail(slice, self.start, slice.len())
- }
- }
- }
-
- /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
- /// self[begin ..= end]`.
- ///
- /// Returns a slice of the given string from the byte range
- /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
- /// self[begin .. end + 1]`, except if `end` has the maximum value for
- /// `usize`.
- ///
- /// This operation is `O(1)`.
- ///
- /// # Panics
- ///
- /// Panics if `begin` does not point to the starting byte offset of
- /// a character (as defined by `is_char_boundary`), if `end` does not point
- /// to the ending byte offset of a character (`end + 1` is either a starting
- /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- if *self.end() == usize::MAX {
- None
- } else {
- (*self.start()..self.end() + 1).get(slice)
- }
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- if *self.end() == usize::MAX {
- None
- } else {
- (*self.start()..self.end() + 1).get_mut(slice)
- }
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
- unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
- unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- if *self.end() == usize::MAX {
- str_index_overflow_fail();
- }
- (*self.start()..self.end() + 1).index(slice)
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- if *self.end() == usize::MAX {
- str_index_overflow_fail();
- }
- (*self.start()..self.end() + 1).index_mut(slice)
- }
- }
-
- /// Implements substring slicing with syntax `&self[..= end]` or `&mut
- /// self[..= end]`.
- ///
- /// Returns a slice of the given string from the byte range [0, `end`].
- /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
- /// value for `usize`.
- ///
- /// This operation is `O(1)`.
- ///
- /// # Panics
- ///
- /// Panics if `end` does not point to the ending byte offset of a character
- /// (`end + 1` is either a starting byte offset as defined by
- /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
- type Output = str;
- #[inline]
- fn get(self, slice: &str) -> Option<&Self::Output> {
- if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) }
- }
- #[inline]
- fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
- if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) }
- }
- #[inline]
- unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
- // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
- unsafe { (..self.end + 1).get_unchecked(slice) }
- }
- #[inline]
- unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
- // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
- unsafe { (..self.end + 1).get_unchecked_mut(slice) }
- }
- #[inline]
- fn index(self, slice: &str) -> &Self::Output {
- if self.end == usize::MAX {
- str_index_overflow_fail();
- }
- (..self.end + 1).index(slice)
- }
- #[inline]
- fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- if self.end == usize::MAX {
- str_index_overflow_fail();
- }
- (..self.end + 1).index_mut(slice)
- }
- }
-}
-
-// truncate `&str` to length at most equal to `max`
-// return `true` if it were truncated, and the new str.
-fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
- if max >= s.len() {
- (false, s)
- } else {
- while !s.is_char_boundary(max) {
- max -= 1;
- }
- (true, &s[..max])
- }
-}
+use validations::truncate_to_char_boundary;
#[inline(never)]
#[cold]
@@ -4560,22 +2413,6 @@
}
}
-impl_fn_for_zst! {
- #[derive(Clone)]
- struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
- c.escape_debug_ext(false)
- };
-
- #[derive(Clone)]
- struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
- c.escape_unicode()
- };
- #[derive(Clone)]
- struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
- c.escape_default()
- };
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<[u8]> for str {
#[inline]
@@ -4601,45 +2438,29 @@
}
}
-/// An iterator over the non-whitespace substrings of a string,
-/// separated by any amount of whitespace.
-///
-/// This struct is created by the [`split_whitespace`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`split_whitespace`]: str::split_whitespace
-#[stable(feature = "split_whitespace", since = "1.1.0")]
-#[derive(Clone, Debug)]
-pub struct SplitWhitespace<'a> {
- inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
-}
-
-/// An iterator over the non-ASCII-whitespace substrings of a string,
-/// separated by any amount of ASCII whitespace.
-///
-/// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`split_ascii_whitespace`]: str::split_ascii_whitespace
-#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
-#[derive(Clone, Debug)]
-pub struct SplitAsciiWhitespace<'a> {
- inner: Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
-}
-
-/// An iterator over the substrings of a string,
-/// terminated by a substring matching to a predicate function
-/// Unlike `Split`, it contains the matched part as a terminator
-/// of the subslice.
-///
-/// This struct is created by the [`split_inclusive`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`split_inclusive`]: str::split_inclusive
-#[unstable(feature = "split_inclusive", issue = "72360")]
-pub struct SplitInclusive<'a, P: Pattern<'a>>(SplitInternal<'a, P>);
-
impl_fn_for_zst! {
+ /// A nameable, cloneable fn type
+ #[derive(Clone)]
+ struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> &'a str {
+ let l = line.len();
+ if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
+ else { line }
+ };
+
+ #[derive(Clone)]
+ struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
+ c.escape_debug_ext(false)
+ };
+
+ #[derive(Clone)]
+ struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
+ c.escape_unicode()
+ };
+ #[derive(Clone)]
+ struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
+ c.escape_default()
+ };
+
#[derive(Clone)]
struct IsWhitespace impl Fn = |c: char| -> bool {
c.is_whitespace()
@@ -4666,223 +2487,3 @@
unsafe { from_utf8_unchecked(bytes) }
};
}
-
-#[stable(feature = "split_whitespace", since = "1.1.0")]
-impl<'a> Iterator for SplitWhitespace<'a> {
- type Item = &'a str;
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- self.inner.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
-
- #[inline]
- fn last(mut self) -> Option<&'a str> {
- self.next_back()
- }
-}
-
-#[stable(feature = "split_whitespace", since = "1.1.0")]
-impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a str> {
- self.inner.next_back()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for SplitWhitespace<'_> {}
-
-#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
-impl<'a> Iterator for SplitAsciiWhitespace<'a> {
- type Item = &'a str;
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- self.inner.next()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
-
- #[inline]
- fn last(mut self) -> Option<&'a str> {
- self.next_back()
- }
-}
-
-#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
-impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a str> {
- self.inner.next_back()
- }
-}
-
-#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
-impl FusedIterator for SplitAsciiWhitespace<'_> {}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
- type Item = &'a str;
-
- #[inline]
- fn next(&mut self) -> Option<&'a str> {
- self.0.next_inclusive()
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, P: Pattern<'a, Searcher: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SplitInclusive").field("0", &self.0).finish()
- }
-}
-
-// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
- fn clone(&self) -> Self {
- SplitInclusive(self.0.clone())
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
- for SplitInclusive<'a, P>
-{
- #[inline]
- fn next_back(&mut self) -> Option<&'a str> {
- self.0.next_back_inclusive()
- }
-}
-
-#[unstable(feature = "split_inclusive", issue = "72360")]
-impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {}
-
-/// An iterator of [`u16`] over the string encoded as UTF-16.
-///
-/// This struct is created by the [`encode_utf16`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`encode_utf16`]: str::encode_utf16
-#[derive(Clone)]
-#[stable(feature = "encode_utf16", since = "1.8.0")]
-pub struct EncodeUtf16<'a> {
- chars: Chars<'a>,
- extra: u16,
-}
-
-#[stable(feature = "collection_debug", since = "1.17.0")]
-impl fmt::Debug for EncodeUtf16<'_> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad("EncodeUtf16 { .. }")
- }
-}
-
-#[stable(feature = "encode_utf16", since = "1.8.0")]
-impl<'a> Iterator for EncodeUtf16<'a> {
- type Item = u16;
-
- #[inline]
- fn next(&mut self) -> Option<u16> {
- if self.extra != 0 {
- let tmp = self.extra;
- self.extra = 0;
- return Some(tmp);
- }
-
- let mut buf = [0; 2];
- self.chars.next().map(|ch| {
- let n = ch.encode_utf16(&mut buf).len();
- if n == 2 {
- self.extra = buf[1];
- }
- buf[0]
- })
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (low, high) = self.chars.size_hint();
- // every char gets either one u16 or two u16,
- // so this iterator is between 1 or 2 times as
- // long as the underlying iterator.
- (low, high.and_then(|n| n.checked_mul(2)))
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl FusedIterator for EncodeUtf16<'_> {}
-
-/// The return type of [`str::escape_debug`].
-#[stable(feature = "str_escape", since = "1.34.0")]
-#[derive(Clone, Debug)]
-pub struct EscapeDebug<'a> {
- inner: Chain<
- Flatten<option::IntoIter<char::EscapeDebug>>,
- FlatMap<Chars<'a>, char::EscapeDebug, CharEscapeDebugContinue>,
- >,
-}
-
-/// The return type of [`str::escape_default`].
-#[stable(feature = "str_escape", since = "1.34.0")]
-#[derive(Clone, Debug)]
-pub struct EscapeDefault<'a> {
- inner: FlatMap<Chars<'a>, char::EscapeDefault, CharEscapeDefault>,
-}
-
-/// The return type of [`str::escape_unicode`].
-#[stable(feature = "str_escape", since = "1.34.0")]
-#[derive(Clone, Debug)]
-pub struct EscapeUnicode<'a> {
- inner: FlatMap<Chars<'a>, char::EscapeUnicode, CharEscapeUnicode>,
-}
-
-macro_rules! escape_types_impls {
- ($( $Name: ident ),+) => {$(
- #[stable(feature = "str_escape", since = "1.34.0")]
- impl<'a> fmt::Display for $Name<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.clone().try_for_each(|c| f.write_char(c))
- }
- }
-
- #[stable(feature = "str_escape", since = "1.34.0")]
- impl<'a> Iterator for $Name<'a> {
- type Item = char;
-
- #[inline]
- fn next(&mut self) -> Option<char> { self.inner.next() }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
- Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
- {
- self.inner.try_fold(init, fold)
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.inner.fold(init, fold)
- }
- }
-
- #[stable(feature = "str_escape", since = "1.34.0")]
- impl<'a> FusedIterator for $Name<'a> {}
- )+}
-}
-
-escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);
diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs
index 1cc2de5..508c522 100644
--- a/library/core/src/str/pattern.rs
+++ b/library/core/src/str/pattern.rs
@@ -28,7 +28,7 @@
//! assert_eq!(s.find(|c: char| c.is_ascii_punctuation()), Some(35));
//! ```
//!
-//! [pattern-impls]: trait.Pattern.html#implementors
+//! [pattern-impls]: Pattern#implementors
#![unstable(
feature = "pattern",
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
new file mode 100644
index 0000000..4f8aa24
--- /dev/null
+++ b/library/core/src/str/traits.rs
@@ -0,0 +1,597 @@
+//! Trait implementations for `str`.
+
+use crate::cmp::Ordering;
+use crate::ops;
+use crate::ptr;
+use crate::slice::SliceIndex;
+
+use super::ParseBoolError;
+
+/// Implements ordering of strings.
+///
+/// Strings are ordered lexicographically by their byte values. This orders Unicode code
+/// points based on their positions in the code charts. This is not necessarily the same as
+/// "alphabetical" order, which varies by language and locale. Sorting strings according to
+/// culturally-accepted standards requires locale-specific data that is outside the scope of
+/// the `str` type.
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Ord for str {
+ #[inline]
+ fn cmp(&self, other: &str) -> Ordering {
+ self.as_bytes().cmp(other.as_bytes())
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for str {
+ #[inline]
+ fn eq(&self, other: &str) -> bool {
+ self.as_bytes() == other.as_bytes()
+ }
+ #[inline]
+ fn ne(&self, other: &str) -> bool {
+ !(*self).eq(other)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Eq for str {}
+
+/// Implements comparison operations on strings.
+///
+/// Strings are compared lexicographically by their byte values. This compares Unicode code
+/// points based on their positions in the code charts. This is not necessarily the same as
+/// "alphabetical" order, which varies by language and locale. Comparing strings according to
+/// culturally-accepted standards requires locale-specific data that is outside the scope of
+/// the `str` type.
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialOrd for str {
+ #[inline]
+ fn partial_cmp(&self, other: &str) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ops::Index<I> for str
+where
+ I: SliceIndex<str>,
+{
+ type Output = I::Output;
+
+ #[inline]
+ fn index(&self, index: I) -> &I::Output {
+ index.index(self)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ops::IndexMut<I> for str
+where
+ I: SliceIndex<str>,
+{
+ #[inline]
+ fn index_mut(&mut self, index: I) -> &mut I::Output {
+ index.index_mut(self)
+ }
+}
+
+#[inline(never)]
+#[cold]
+#[track_caller]
+fn str_index_overflow_fail() -> ! {
+ panic!("attempted to index str up to maximum usize");
+}
+
+/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
+///
+/// Returns a slice of the whole string, i.e., returns `&self` or `&mut
+/// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
+/// other indexing operations, this can never panic.
+///
+/// This operation is `O(1)`.
+///
+/// Prior to 1.20.0, these indexing operations were still supported by
+/// direct implementation of `Index` and `IndexMut`.
+///
+/// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
+#[stable(feature = "str_checked_slicing", since = "1.20.0")]
+unsafe impl SliceIndex<str> for ops::RangeFull {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ Some(slice)
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ Some(slice)
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ slice
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ slice
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ slice
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ slice
+ }
+}
+
+/// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
+/// self[begin .. end]`.
+///
+/// Returns a slice of the given string from the byte range
+/// [`begin`, `end`).
+///
+/// This operation is `O(1)`.
+///
+/// Prior to 1.20.0, these indexing operations were still supported by
+/// direct implementation of `Index` and `IndexMut`.
+///
+/// # Panics
+///
+/// Panics if `begin` or `end` does not point to the starting byte offset of
+/// a character (as defined by `is_char_boundary`), if `begin > end`, or if
+/// `end > len`.
+///
+/// # Examples
+///
+/// ```
+/// let s = "Löwe čč Léopard";
+/// assert_eq!(&s[0 .. 1], "L");
+///
+/// assert_eq!(&s[1 .. 9], "öwe č");
+///
+/// // these will panic:
+/// // byte 2 lies within `ö`:
+/// // &s[2 ..3];
+///
+/// // byte 8 lies within `č`
+/// // &s[1 .. 8];
+///
+/// // byte 100 is outside the string
+/// // &s[3 .. 100];
+/// ```
+#[stable(feature = "str_checked_slicing", since = "1.20.0")]
+unsafe impl SliceIndex<str> for ops::Range<usize> {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ if self.start <= self.end
+ && slice.is_char_boundary(self.start)
+ && slice.is_char_boundary(self.end)
+ {
+ // SAFETY: just checked that `start` and `end` are on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ // We also checked char boundaries, so this is valid UTF-8.
+ Some(unsafe { &*self.get_unchecked(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ if self.start <= self.end
+ && slice.is_char_boundary(self.start)
+ && slice.is_char_boundary(self.end)
+ {
+ // SAFETY: just checked that `start` and `end` are on a char boundary.
+ // We know the pointer is unique because we got it from `slice`.
+ Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ let slice = slice as *const [u8];
+ // SAFETY: the caller guarantees that `self` is in bounds of `slice`
+ // which satisfies all the conditions for `add`.
+ let ptr = unsafe { slice.as_ptr().add(self.start) };
+ let len = self.end - self.start;
+ ptr::slice_from_raw_parts(ptr, len) as *const str
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ let slice = slice as *mut [u8];
+ // SAFETY: see comments for `get_unchecked`.
+ let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
+ let len = self.end - self.start;
+ ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ let (start, end) = (self.start, self.end);
+ match self.get(slice) {
+ Some(s) => s,
+ None => super::slice_error_fail(slice, start, end),
+ }
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ // is_char_boundary checks that the index is in [0, .len()]
+ // cannot reuse `get` as above, because of NLL trouble
+ if self.start <= self.end
+ && slice.is_char_boundary(self.start)
+ && slice.is_char_boundary(self.end)
+ {
+ // SAFETY: just checked that `start` and `end` are on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ unsafe { &mut *self.get_unchecked_mut(slice) }
+ } else {
+ super::slice_error_fail(slice, self.start, self.end)
+ }
+ }
+}
+
+/// Implements substring slicing with syntax `&self[.. end]` or `&mut
+/// self[.. end]`.
+///
+/// Returns a slice of the given string from the byte range [`0`, `end`).
+/// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
+///
+/// This operation is `O(1)`.
+///
+/// Prior to 1.20.0, these indexing operations were still supported by
+/// direct implementation of `Index` and `IndexMut`.
+///
+/// # Panics
+///
+/// Panics if `end` does not point to the starting byte offset of a
+/// character (as defined by `is_char_boundary`), or if `end > len`.
+#[stable(feature = "str_checked_slicing", since = "1.20.0")]
+unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ Some(unsafe { &*self.get_unchecked(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ let slice = slice as *const [u8];
+ let ptr = slice.as_ptr();
+ ptr::slice_from_raw_parts(ptr, self.end) as *const str
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ let slice = slice as *mut [u8];
+ let ptr = slice.as_mut_ptr();
+ ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ let end = self.end;
+ match self.get(slice) {
+ Some(s) => s,
+ None => super::slice_error_fail(slice, 0, end),
+ }
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ unsafe { &mut *self.get_unchecked_mut(slice) }
+ } else {
+ super::slice_error_fail(slice, 0, self.end)
+ }
+ }
+}
+
+/// Implements substring slicing with syntax `&self[begin ..]` or `&mut
+/// self[begin ..]`.
+///
+/// Returns a slice of the given string from the byte range [`begin`,
+/// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin ..
+/// len]`.
+///
+/// This operation is `O(1)`.
+///
+/// Prior to 1.20.0, these indexing operations were still supported by
+/// direct implementation of `Index` and `IndexMut`.
+///
+/// # Panics
+///
+/// Panics if `begin` does not point to the starting byte offset of
+/// a character (as defined by `is_char_boundary`), or if `begin > len`.
+#[stable(feature = "str_checked_slicing", since = "1.20.0")]
+unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ Some(unsafe { &*self.get_unchecked(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ let slice = slice as *const [u8];
+ // SAFETY: the caller guarantees that `self` is in bounds of `slice`
+ // which satisfies all the conditions for `add`.
+ let ptr = unsafe { slice.as_ptr().add(self.start) };
+ let len = slice.len() - self.start;
+ ptr::slice_from_raw_parts(ptr, len) as *const str
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ let slice = slice as *mut [u8];
+ // SAFETY: identical to `get_unchecked`.
+ let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
+ let len = slice.len() - self.start;
+ ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ let (start, end) = (self.start, slice.len());
+ match self.get(slice) {
+ Some(s) => s,
+ None => super::slice_error_fail(slice, start, end),
+ }
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary,
+ // and we are passing in a safe reference, so the return value will also be one.
+ unsafe { &mut *self.get_unchecked_mut(slice) }
+ } else {
+ super::slice_error_fail(slice, self.start, slice.len())
+ }
+ }
+}
+
+/// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
+/// self[begin ..= end]`.
+///
+/// Returns a slice of the given string from the byte range
+/// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
+/// self[begin .. end + 1]`, except if `end` has the maximum value for
+/// `usize`.
+///
+/// This operation is `O(1)`.
+///
+/// # Panics
+///
+/// Panics if `begin` does not point to the starting byte offset of
+/// a character (as defined by `is_char_boundary`), if `end` does not point
+/// to the ending byte offset of a character (`end + 1` is either a starting
+/// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ if *self.end() == usize::MAX {
+ None
+ } else {
+ (*self.start()..self.end() + 1).get_mut(slice)
+ }
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
+ unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ if *self.end() == usize::MAX {
+ str_index_overflow_fail();
+ }
+ (*self.start()..self.end() + 1).index(slice)
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ if *self.end() == usize::MAX {
+ str_index_overflow_fail();
+ }
+ (*self.start()..self.end() + 1).index_mut(slice)
+ }
+}
+
+/// Implements substring slicing with syntax `&self[..= end]` or `&mut
+/// self[..= end]`.
+///
+/// Returns a slice of the given string from the byte range [0, `end`].
+/// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
+/// value for `usize`.
+///
+/// This operation is `O(1)`.
+///
+/// # Panics
+///
+/// Panics if `end` does not point to the ending byte offset of a character
+/// (`end + 1` is either a starting byte offset as defined by
+/// `is_char_boundary`, or equal to `len`), or if `end >= len`.
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
+ type Output = str;
+ #[inline]
+ fn get(self, slice: &str) -> Option<&Self::Output> {
+ if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) }
+ }
+ #[inline]
+ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+ if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) }
+ }
+ #[inline]
+ unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
+ unsafe { (..self.end + 1).get_unchecked(slice) }
+ }
+ #[inline]
+ unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
+ unsafe { (..self.end + 1).get_unchecked_mut(slice) }
+ }
+ #[inline]
+ fn index(self, slice: &str) -> &Self::Output {
+ if self.end == usize::MAX {
+ str_index_overflow_fail();
+ }
+ (..self.end + 1).index(slice)
+ }
+ #[inline]
+ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+ if self.end == usize::MAX {
+ str_index_overflow_fail();
+ }
+ (..self.end + 1).index_mut(slice)
+ }
+}
+
+/// Parse a value from a string
+///
+/// `FromStr`'s [`from_str`] method is often used implicitly, through
+/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
+///
+/// [`from_str`]: FromStr::from_str
+/// [`parse`]: str::parse
+///
+/// `FromStr` does not have a lifetime parameter, and so you can only parse types
+/// that do not contain a lifetime parameter themselves. In other words, you can
+/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
+/// contains an `i32`, but not one that contains an `&i32`.
+///
+/// # Examples
+///
+/// Basic implementation of `FromStr` on an example `Point` type:
+///
+/// ```
+/// use std::str::FromStr;
+/// use std::num::ParseIntError;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Point {
+/// x: i32,
+/// y: i32
+/// }
+///
+/// impl FromStr for Point {
+/// type Err = ParseIntError;
+///
+/// fn from_str(s: &str) -> Result<Self, Self::Err> {
+/// let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
+/// .split(',')
+/// .collect();
+///
+/// let x_fromstr = coords[0].parse::<i32>()?;
+/// let y_fromstr = coords[1].parse::<i32>()?;
+///
+/// Ok(Point { x: x_fromstr, y: y_fromstr })
+/// }
+/// }
+///
+/// let p = Point::from_str("(1,2)");
+/// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait FromStr: Sized {
+ /// The associated error which can be returned from parsing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ type Err;
+
+ /// Parses a string `s` to return a value of this type.
+ ///
+ /// If parsing succeeds, return the value inside [`Ok`], otherwise
+ /// when the string is ill-formatted return an error specific to the
+ /// inside [`Err`]. The error type is specific to implementation of the trait.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage with [`i32`][ithirtytwo], a type that implements `FromStr`:
+ ///
+ /// [ithirtytwo]: ../../std/primitive.i32.html
+ ///
+ /// ```
+ /// use std::str::FromStr;
+ ///
+ /// let s = "5";
+ /// let x = i32::from_str(s).unwrap();
+ ///
+ /// assert_eq!(5, x);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from_str(s: &str) -> Result<Self, Self::Err>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl FromStr for bool {
+ type Err = ParseBoolError;
+
+ /// Parse a `bool` from a string.
+ ///
+ /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
+ /// actually be parseable.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::str::FromStr;
+ ///
+ /// assert_eq!(FromStr::from_str("true"), Ok(true));
+ /// assert_eq!(FromStr::from_str("false"), Ok(false));
+ /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
+ /// ```
+ ///
+ /// Note, in many cases, the `.parse()` method on `str` is more proper.
+ ///
+ /// ```
+ /// assert_eq!("true".parse(), Ok(true));
+ /// assert_eq!("false".parse(), Ok(false));
+ /// assert!("not even a boolean".parse::<bool>().is_err());
+ /// ```
+ #[inline]
+ fn from_str(s: &str) -> Result<bool, ParseBoolError> {
+ match s {
+ "true" => Ok(true),
+ "false" => Ok(false),
+ _ => Err(ParseBoolError { _priv: () }),
+ }
+ }
+}
diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs
new file mode 100644
index 0000000..10cf1e1
--- /dev/null
+++ b/library/core/src/str/validations.rs
@@ -0,0 +1,275 @@
+//! Operations related to UTF-8 validation.
+
+use crate::mem;
+
+use super::Utf8Error;
+
+/// Returns the initial codepoint accumulator for the first byte.
+/// The first byte is special, only want bottom 5 bits for width 2, 4 bits
+/// for width 3, and 3 bits for width 4.
+#[inline]
+fn utf8_first_byte(byte: u8, width: u32) -> u32 {
+ (byte & (0x7F >> width)) as u32
+}
+
+/// Returns the value of `ch` updated with continuation byte `byte`.
+#[inline]
+fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 {
+ (ch << 6) | (byte & CONT_MASK) as u32
+}
+
+/// Checks whether the byte is a UTF-8 continuation byte (i.e., starts with the
+/// bits `10`).
+#[inline]
+pub(super) fn utf8_is_cont_byte(byte: u8) -> bool {
+ (byte & !CONT_MASK) == TAG_CONT_U8
+}
+
+#[inline]
+fn unwrap_or_0(opt: Option<&u8>) -> u8 {
+ match opt {
+ Some(&byte) => byte,
+ None => 0,
+ }
+}
+
+/// Reads the next code point out of a byte iterator (assuming a
+/// UTF-8-like encoding).
+#[unstable(feature = "str_internals", issue = "none")]
+#[inline]
+pub fn next_code_point<'a, I: Iterator<Item = &'a u8>>(bytes: &mut I) -> Option<u32> {
+ // Decode UTF-8
+ let x = *bytes.next()?;
+ if x < 128 {
+ return Some(x as u32);
+ }
+
+ // Multibyte case follows
+ // Decode from a byte combination out of: [[[x y] z] w]
+ // NOTE: Performance is sensitive to the exact formulation here
+ let init = utf8_first_byte(x, 2);
+ let y = unwrap_or_0(bytes.next());
+ let mut ch = utf8_acc_cont_byte(init, y);
+ if x >= 0xE0 {
+ // [[x y z] w] case
+ // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
+ let z = unwrap_or_0(bytes.next());
+ let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
+ ch = init << 12 | y_z;
+ if x >= 0xF0 {
+ // [x y z w] case
+ // use only the lower 3 bits of `init`
+ let w = unwrap_or_0(bytes.next());
+ ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
+ }
+ }
+
+ Some(ch)
+}
+
+/// Reads the last code point out of a byte iterator (assuming a
+/// UTF-8-like encoding).
+#[inline]
+pub(super) fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option<u32>
+where
+ I: DoubleEndedIterator<Item = &'a u8>,
+{
+ // Decode UTF-8
+ let w = match *bytes.next_back()? {
+ next_byte if next_byte < 128 => return Some(next_byte as u32),
+ back_byte => back_byte,
+ };
+
+ // Multibyte case follows
+ // Decode from a byte combination out of: [x [y [z w]]]
+ let mut ch;
+ let z = unwrap_or_0(bytes.next_back());
+ ch = utf8_first_byte(z, 2);
+ if utf8_is_cont_byte(z) {
+ let y = unwrap_or_0(bytes.next_back());
+ ch = utf8_first_byte(y, 3);
+ if utf8_is_cont_byte(y) {
+ let x = unwrap_or_0(bytes.next_back());
+ ch = utf8_first_byte(x, 4);
+ ch = utf8_acc_cont_byte(ch, y);
+ }
+ ch = utf8_acc_cont_byte(ch, z);
+ }
+ ch = utf8_acc_cont_byte(ch, w);
+
+ Some(ch)
+}
+
+// use truncation to fit u64 into usize
+const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
+
+/// Returns `true` if any byte in the word `x` is nonascii (>= 128).
+#[inline]
+fn contains_nonascii(x: usize) -> bool {
+ (x & NONASCII_MASK) != 0
+}
+
+/// Walks through `v` checking that it's a valid UTF-8 sequence,
+/// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`.
+#[inline(always)]
+pub(super) fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
+ let mut index = 0;
+ let len = v.len();
+
+ let usize_bytes = mem::size_of::<usize>();
+ let ascii_block_size = 2 * usize_bytes;
+ let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 };
+ let align = v.as_ptr().align_offset(usize_bytes);
+
+ while index < len {
+ let old_offset = index;
+ macro_rules! err {
+ ($error_len: expr) => {
+ return Err(Utf8Error { valid_up_to: old_offset, error_len: $error_len });
+ };
+ }
+
+ macro_rules! next {
+ () => {{
+ index += 1;
+ // we needed data, but there was none: error!
+ if index >= len {
+ err!(None)
+ }
+ v[index]
+ }};
+ }
+
+ let first = v[index];
+ if first >= 128 {
+ let w = UTF8_CHAR_WIDTH[first as usize];
+ // 2-byte encoding is for codepoints \u{0080} to \u{07ff}
+ // first C2 80 last DF BF
+ // 3-byte encoding is for codepoints \u{0800} to \u{ffff}
+ // first E0 A0 80 last EF BF BF
+ // excluding surrogates codepoints \u{d800} to \u{dfff}
+ // ED A0 80 to ED BF BF
+ // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
+ // first F0 90 80 80 last F4 8F BF BF
+ //
+ // Use the UTF-8 syntax from the RFC
+ //
+ // https://tools.ietf.org/html/rfc3629
+ // UTF8-1 = %x00-7F
+ // UTF8-2 = %xC2-DF UTF8-tail
+ // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+ // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+ // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+ // %xF4 %x80-8F 2( UTF8-tail )
+ match w {
+ 2 => {
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(1))
+ }
+ }
+ 3 => {
+ match (first, next!()) {
+ (0xE0, 0xA0..=0xBF)
+ | (0xE1..=0xEC, 0x80..=0xBF)
+ | (0xED, 0x80..=0x9F)
+ | (0xEE..=0xEF, 0x80..=0xBF) => {}
+ _ => err!(Some(1)),
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(2))
+ }
+ }
+ 4 => {
+ match (first, next!()) {
+ (0xF0, 0x90..=0xBF) | (0xF1..=0xF3, 0x80..=0xBF) | (0xF4, 0x80..=0x8F) => {}
+ _ => err!(Some(1)),
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(2))
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(3))
+ }
+ }
+ _ => err!(Some(1)),
+ }
+ index += 1;
+ } else {
+ // Ascii case, try to skip forward quickly.
+ // When the pointer is aligned, read 2 words of data per iteration
+ // until we find a word containing a non-ascii byte.
+ if align != usize::MAX && align.wrapping_sub(index) % usize_bytes == 0 {
+ let ptr = v.as_ptr();
+ while index < blocks_end {
+ // SAFETY: since `align - index` and `ascii_block_size` are
+ // multiples of `usize_bytes`, `block = ptr.add(index)` is
+ // always aligned with a `usize` so it's safe to dereference
+ // both `block` and `block.offset(1)`.
+ unsafe {
+ let block = ptr.add(index) as *const usize;
+ // break if there is a nonascii byte
+ let zu = contains_nonascii(*block);
+ let zv = contains_nonascii(*block.offset(1));
+ if zu | zv {
+ break;
+ }
+ }
+ index += ascii_block_size;
+ }
+ // step from the point where the wordwise loop stopped
+ while index < len && v[index] < 128 {
+ index += 1;
+ }
+ } else {
+ index += 1;
+ }
+ }
+ }
+
+ Ok(())
+}
+
+// https://tools.ietf.org/html/rfc3629
+static UTF8_CHAR_WIDTH: [u8; 256] = [
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, // 0x1F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, // 0x3F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, // 0x5F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, // 0x7F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, // 0x9F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, // 0xBF
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, // 0xDF
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF
+];
+
+/// Given a first byte, determines how many bytes are in this UTF-8 character.
+#[unstable(feature = "str_internals", issue = "none")]
+#[inline]
+pub fn utf8_char_width(b: u8) -> usize {
+ UTF8_CHAR_WIDTH[b as usize] as usize
+}
+
+/// Mask of the value bits of a continuation byte.
+const CONT_MASK: u8 = 0b0011_1111;
+/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte.
+const TAG_CONT_U8: u8 = 0b1000_0000;
+
+// truncate `&str` to length at most equal to `max`
+// return `true` if it were truncated, and the new str.
+pub(super) fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
+ if max >= s.len() {
+ (false, s)
+ } else {
+ while !s.is_char_boundary(max) {
+ max -= 1;
+ }
+ (true, &s[..max])
+ }
+}
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index f31a4a0..5c9cfe2 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -10,18 +10,10 @@
//! Atomic types present operations that, when used correctly, synchronize
//! updates between threads.
//!
-//! [`AtomicBool`]: struct.AtomicBool.html
-//! [`AtomicIsize`]: struct.AtomicIsize.html
-//! [`AtomicUsize`]: struct.AtomicUsize.html
-//! [`AtomicI8`]: struct.AtomicI8.html
-//! [`AtomicU16`]: struct.AtomicU16.html
-//!
//! Each method takes an [`Ordering`] which represents the strength of
//! the memory barrier for that operation. These orderings are the
//! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2].
//!
-//! [`Ordering`]: enum.Ordering.html
-//!
//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
//! [2]: ../../../nomicon/atomics.html
//!
@@ -31,15 +23,12 @@
//! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
//! atomically-reference-counted shared pointer).
//!
-//! [`Sync`]: ../../marker/trait.Sync.html
//! [arc]: ../../../std/sync/struct.Arc.html
//!
//! Atomic types may be stored in static variables, initialized using
//! the constant initializers like [`AtomicBool::new`]. Atomic statics
//! are often used for lazy global initialization.
//!
-//! [`AtomicBool::new`]: struct.AtomicBool.html#method.new
-//!
//! # Portability
//!
//! All atomic types in this module are guaranteed to be [lock-free] if they're
@@ -87,7 +76,7 @@
//! fn main() {
//! let spinlock = Arc::new(AtomicUsize::new(1));
//!
-//! let spinlock_clone = spinlock.clone();
+//! let spinlock_clone = Arc::clone(&spinlock);
//! let thread = thread::spawn(move|| {
//! spinlock_clone.store(0, Ordering::SeqCst);
//! });
@@ -155,8 +144,6 @@
///
/// **Note**: This type is only available on platforms that support atomic
/// loads and stores of `u8`.
-///
-/// [`bool`]: ../../../std/primitive.bool.html
#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(C, align(1))]
@@ -212,8 +199,8 @@
/// Atomic memory orderings
///
/// Memory orderings specify the way atomic operations synchronize memory.
-/// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the
-/// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst]
+/// In its weakest [`Ordering::Relaxed`], only the memory directly touched by the
+/// operation is synchronized. On the other hand, a store-load pair of [`Ordering::SeqCst`]
/// operations synchronize other memory while additionally preserving a total order of such
/// operations across all threads.
///
@@ -223,8 +210,6 @@
/// For more information see the [nomicon].
///
/// [nomicon]: ../../../nomicon/atomics.html
-/// [Ordering::Relaxed]: #variant.Relaxed
-/// [Ordering::SeqCst]: #variant.SeqCst
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[non_exhaustive]
@@ -248,9 +233,6 @@
///
/// Corresponds to [`memory_order_release`] in C++20.
///
- /// [`Release`]: #variant.Release
- /// [`Acquire`]: #variant.Acquire
- /// [`Relaxed`]: #variant.Relaxed
/// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
#[stable(feature = "rust1", since = "1.0.0")]
Release,
@@ -266,9 +248,6 @@
///
/// Corresponds to [`memory_order_acquire`] in C++20.
///
- /// [`Acquire`]: #variant.Acquire
- /// [`Release`]: #variant.Release
- /// [`Relaxed`]: #variant.Relaxed
/// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
#[stable(feature = "rust1", since = "1.0.0")]
Acquire,
@@ -284,9 +263,6 @@
/// Corresponds to [`memory_order_acq_rel`] in C++20.
///
/// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
- /// [`Acquire`]: #variant.Acquire
- /// [`Release`]: #variant.Release
- /// [`Relaxed`]: #variant.Relaxed
#[stable(feature = "rust1", since = "1.0.0")]
AcqRel,
/// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
@@ -296,16 +272,11 @@
/// Corresponds to [`memory_order_seq_cst`] in C++20.
///
/// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
- /// [`Acquire`]: #variant.Acquire
- /// [`Release`]: #variant.Release
- /// [`AcqRel`]: #variant.AcqRel
#[stable(feature = "rust1", since = "1.0.0")]
SeqCst,
}
/// An [`AtomicBool`] initialized to `false`.
-///
-/// [`AtomicBool`]: struct.AtomicBool.html
#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(
@@ -339,8 +310,6 @@
/// This is safe because the mutable reference guarantees that no other threads are
/// concurrently accessing the atomic data.
///
- /// [`bool`]: ../../../std/primitive.bool.html
- ///
/// # Examples
///
/// ```
@@ -358,6 +327,28 @@
unsafe { &mut *(self.v.get() as *mut bool) }
}
+ /// Get atomic access to a `&mut bool`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(atomic_from_mut)]
+ /// use std::sync::atomic::{AtomicBool, Ordering};
+ ///
+ /// let mut some_bool = true;
+ /// let a = AtomicBool::from_mut(&mut some_bool);
+ /// a.store(false, Ordering::Relaxed);
+ /// assert_eq!(some_bool, false);
+ /// ```
+ #[inline]
+ #[cfg(target_has_atomic_equal_alignment = "8")]
+ #[unstable(feature = "atomic_from_mut", issue = "76314")]
+ pub fn from_mut(v: &mut bool) -> &Self {
+ // SAFETY: the mutable reference guarantees unique ownership, and
+ // alignment of both `bool` and `Self` is 1.
+ unsafe { &*(v as *mut bool 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
@@ -386,13 +377,6 @@
///
/// Panics if `order` is [`Release`] or [`AcqRel`].
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -419,13 +403,6 @@
///
/// Panics if `order` is [`Acquire`] or [`AcqRel`].
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -456,11 +433,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// # Examples
///
/// ```
@@ -493,13 +465,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- /// [`bool`]: ../../../std/primitive.bool.html
- ///
/// # Examples
///
/// ```
@@ -539,13 +504,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`bool`]: ../../../std/primitive.bool.html
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -587,7 +545,7 @@
/// Stores a value into the [`bool`] if the current value is the same as the `current` value.
///
- /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
+ /// Unlike [`AtomicBool::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.
@@ -603,14 +561,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`bool`]: ../../../std/primitive.bool.html
- /// [`compare_exchange`]: #method.compare_exchange
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -658,11 +608,6 @@
/// [`Acquire`] makes the store part of this operation [`Relaxed`], and
/// using [`Release`] makes the load part [`Relaxed`].
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
@@ -706,11 +651,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// # Examples
///
/// ```
@@ -763,11 +703,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// # Examples
///
/// ```
@@ -808,11 +743,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on `u8`.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// # Examples
///
/// ```
@@ -850,8 +780,6 @@
/// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
/// restriction: operations on it must be atomic.
///
- /// [`bool`]: ../../../std/primitive.bool.html
- ///
/// # Examples
///
/// ```ignore (extern-declaration)
@@ -910,8 +838,33 @@
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn get_mut(&mut self) -> &mut *mut T {
- // SAFETY: the mutable reference guarantees unique ownership.
- unsafe { &mut *self.p.get() }
+ self.p.get_mut()
+ }
+
+ /// Get atomic access to a pointer.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(atomic_from_mut)]
+ /// use std::sync::atomic::{AtomicPtr, Ordering};
+ ///
+ /// let mut some_ptr = &mut 123 as *mut i32;
+ /// let a = AtomicPtr::from_mut(&mut some_ptr);
+ /// a.store(&mut 456, Ordering::Relaxed);
+ /// assert_eq!(unsafe { *some_ptr }, 456);
+ /// ```
+ #[inline]
+ #[cfg(target_has_atomic_equal_alignment = "ptr")]
+ #[unstable(feature = "atomic_from_mut", issue = "76314")]
+ pub fn from_mut(v: &mut *mut T) -> &Self {
+ use crate::mem::align_of;
+ let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
+ // SAFETY:
+ // - the mutable reference guarantees unique ownership.
+ // - the alignment of `*mut T` and `Self` is the same on all platforms
+ // supported by rust, as verified above.
+ unsafe { &*(v as *mut *mut T as *mut Self) }
}
/// Consumes the atomic and returns the contained value.
@@ -942,13 +895,6 @@
///
/// Panics if `order` is [`Release`] or [`AcqRel`].
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -975,13 +921,6 @@
///
/// Panics if `order` is [`Acquire`] or [`AcqRel`].
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -1013,11 +952,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on pointers.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- ///
/// # Examples
///
/// ```
@@ -1052,12 +986,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on pointers.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
- ///
/// # Examples
///
/// ```
@@ -1096,12 +1024,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on pointers.
///
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -1143,7 +1065,7 @@
/// Stores a value into the pointer if the current value is the same as the `current` value.
///
- /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
+ /// Unlike [`AtomicPtr::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.
@@ -1159,13 +1081,6 @@
/// **Note:** This method is only available on platforms that support atomic
/// operations on pointers.
///
- /// [`compare_exchange`]: #method.compare_exchange
- /// [`Ordering`]: enum.Ordering.html
- /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
- /// [`Release`]: enum.Ordering.html#variant.Release
- /// [`Acquire`]: enum.Ordering.html#variant.Acquire
- /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
- ///
/// # Examples
///
/// ```
@@ -1236,9 +1151,17 @@
}
}
+#[allow(unused_macros)] // This macro ends up being unused on some architectures.
+macro_rules! if_not_8_bit {
+ (u8, $($tt:tt)*) => { "" };
+ (i8, $($tt:tt)*) => { "" };
+ ($_:ident, $($tt:tt)*) => { $($tt)* };
+}
+
#[cfg(target_has_atomic_load_store = "8")]
macro_rules! atomic_int {
($cfg_cas:meta,
+ $cfg_align:meta,
$stable:meta,
$stable_cxchg:meta,
$stable_debug:meta,
@@ -1247,7 +1170,7 @@
$stable_nand:meta,
$const_stable:meta,
$stable_init_const:meta,
- $s_int_type:expr, $int_ref:expr,
+ $s_int_type:literal, $int_ref:expr,
$extra_feature:expr,
$min_fn:ident, $max_fn:ident,
$align:expr,
@@ -1271,7 +1194,7 @@
#[doc = $int_ref]
/// ).
///
- /// [module-level documentation]: index.html
+ /// [module-level documentation]: crate::sync::atomic
#[$stable]
#[repr(C, align($align))]
pub struct $atomic_type {
@@ -1353,8 +1276,46 @@
#[inline]
#[$stable_access]
pub fn get_mut(&mut self) -> &mut $int_type {
- // SAFETY: the mutable reference guarantees unique ownership.
- unsafe { &mut *self.v.get() }
+ self.v.get_mut()
+ }
+ }
+
+ doc_comment! {
+ concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.
+
+",
+if_not_8_bit! {
+ $int_type,
+ concat!(
+ "**Note:** This function is only available on targets where `",
+ stringify!($int_type), "` has an alignment of ", $align, " bytes."
+ )
+},
+"
+
+# Examples
+
+```
+#![feature(atomic_from_mut)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let mut some_int = 123;
+let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);
+a.store(100, Ordering::Relaxed);
+assert_eq!(some_int, 100);
+```
+ "),
+ #[inline]
+ #[$cfg_align]
+ #[unstable(feature = "atomic_from_mut", issue = "76314")]
+ pub fn from_mut(v: &mut $int_type) -> &Self {
+ use crate::mem::align_of;
+ let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
+ // SAFETY:
+ // - the mutable reference guarantees unique ownership.
+ // - the alignment of `$int_type` and `Self` is the
+ // same, as promised by $cfg_align and verified above.
+ unsafe { &*(v as *mut $int_type as *mut Self) }
}
}
@@ -1389,13 +1350,6 @@
Panics if `order` is [`Release`] or [`AcqRel`].
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`AcqRel`]: enum.Ordering.html#variant.AcqRel
-[`SeqCst`]: enum.Ordering.html#variant.SeqCst
-
# Examples
```
@@ -1423,13 +1377,6 @@
Panics if `order` is [`Acquire`] or [`AcqRel`].
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`AcqRel`]: enum.Ordering.html#variant.AcqRel
-[`SeqCst`]: enum.Ordering.html#variant.SeqCst
-
# Examples
```
@@ -1459,11 +1406,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1498,12 +1440,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`AcqRel`]: enum.Ordering.html#variant.AcqRel
-
# Examples
```
@@ -1553,12 +1489,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`SeqCst`]: enum.Ordering.html#variant.SeqCst
-
# Examples
```
@@ -1595,7 +1525,7 @@
concat!("Stores a value into the atomic integer if the current value is the same as
the `current` value.
-Unlike [`compare_exchange`], this function is allowed to spuriously fail even
+Unlike [`", stringify!($atomic_type), "::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.
@@ -1608,13 +1538,6 @@
[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
and must be equivalent to or weaker than the success ordering.
-[`compare_exchange`]: #method.compare_exchange
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`SeqCst`]: enum.Ordering.html#variant.SeqCst
-
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
@@ -1662,11 +1585,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1698,11 +1616,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1737,11 +1650,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1776,11 +1684,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1816,11 +1719,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1855,11 +1753,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -1890,7 +1783,7 @@
`fetch_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
-[`compare_exchange`] respectively.
+[`", stringify!($atomic_type), "::compare_exchange`] respectively.
Using [`Acquire`] as success ordering makes the store part
of this operation [`Relaxed`], and using [`Release`] makes the final successful load
@@ -1900,14 +1793,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`bool`]: ../../../std/primitive.bool.html
-[`compare_exchange`]: #method.compare_exchange
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-[`SeqCst`]: enum.Ordering.html#variant.SeqCst
-
# Examples
```rust
@@ -1954,11 +1839,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -2004,11 +1884,6 @@
**Note**: This method is only available on platforms that support atomic
operations on [`", $s_int_type, "`](", $int_ref, ").
-[`Ordering`]: enum.Ordering.html
-[`Relaxed`]: enum.Ordering.html#variant.Relaxed
-[`Release`]: enum.Ordering.html#variant.Release
-[`Acquire`]: enum.Ordering.html#variant.Acquire
-
# Examples
```
@@ -2086,6 +1961,7 @@
#[cfg(target_has_atomic_load_store = "8")]
atomic_int! {
cfg(target_has_atomic = "8"),
+ cfg(target_has_atomic_equal_alignment = "8"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2104,6 +1980,7 @@
#[cfg(target_has_atomic_load_store = "8")]
atomic_int! {
cfg(target_has_atomic = "8"),
+ cfg(target_has_atomic_equal_alignment = "8"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2122,6 +1999,7 @@
#[cfg(target_has_atomic_load_store = "16")]
atomic_int! {
cfg(target_has_atomic = "16"),
+ cfg(target_has_atomic_equal_alignment = "16"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2140,6 +2018,7 @@
#[cfg(target_has_atomic_load_store = "16")]
atomic_int! {
cfg(target_has_atomic = "16"),
+ cfg(target_has_atomic_equal_alignment = "16"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2158,6 +2037,7 @@
#[cfg(target_has_atomic_load_store = "32")]
atomic_int! {
cfg(target_has_atomic = "32"),
+ cfg(target_has_atomic_equal_alignment = "32"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2176,6 +2056,7 @@
#[cfg(target_has_atomic_load_store = "32")]
atomic_int! {
cfg(target_has_atomic = "32"),
+ cfg(target_has_atomic_equal_alignment = "32"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2194,6 +2075,7 @@
#[cfg(target_has_atomic_load_store = "64")]
atomic_int! {
cfg(target_has_atomic = "64"),
+ cfg(target_has_atomic_equal_alignment = "64"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2212,6 +2094,7 @@
#[cfg(target_has_atomic_load_store = "64")]
atomic_int! {
cfg(target_has_atomic = "64"),
+ cfg(target_has_atomic_equal_alignment = "64"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
stable(feature = "integer_atomics_stable", since = "1.34.0"),
@@ -2230,6 +2113,7 @@
#[cfg(target_has_atomic_load_store = "128")]
atomic_int! {
cfg(target_has_atomic = "128"),
+ cfg(target_has_atomic_equal_alignment = "128"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
@@ -2248,6 +2132,7 @@
#[cfg(target_has_atomic_load_store = "128")]
atomic_int! {
cfg(target_has_atomic = "128"),
+ cfg(target_has_atomic_equal_alignment = "128"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
@@ -2287,6 +2172,7 @@
#[cfg(target_has_atomic_load_store = "ptr")]
atomic_int! {
cfg(target_has_atomic = "ptr"),
+ cfg(target_has_atomic_equal_alignment = "ptr"),
stable(feature = "rust1", since = "1.0.0"),
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
stable(feature = "atomic_debug", since = "1.3.0"),
@@ -2305,6 +2191,7 @@
#[cfg(target_has_atomic_load_store = "ptr")]
atomic_int! {
cfg(target_has_atomic = "ptr"),
+ cfg(target_has_atomic_equal_alignment = "ptr"),
stable(feature = "rust1", since = "1.0.0"),
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
stable(feature = "atomic_debug", since = "1.3.0"),
@@ -2660,13 +2547,6 @@
/// }
/// }
/// ```
-///
-/// [`Ordering`]: enum.Ordering.html
-/// [`Acquire`]: enum.Ordering.html#variant.Acquire
-/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
-/// [`Release`]: enum.Ordering.html#variant.Release
-/// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-/// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn fence(order: Ordering) {
@@ -2747,13 +2627,6 @@
/// }
/// ```
///
-/// [`fence`]: fn.fence.html
-/// [`Ordering`]: enum.Ordering.html
-/// [`Acquire`]: enum.Ordering.html#variant.Acquire
-/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
-/// [`Release`]: enum.Ordering.html#variant.Release
-/// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-/// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
/// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
#[inline]
#[stable(feature = "compiler_fences", since = "1.21.0")]
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index fea396d..4e987a5 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -10,7 +10,7 @@
#[stable(feature = "futures_api", since = "1.36.0")]
pub enum Poll<T> {
/// Represents that a value is immediately ready.
- #[cfg_attr(not(bootstrap), lang = "Ready")]
+ #[lang = "Ready"]
#[stable(feature = "futures_api", since = "1.36.0")]
Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
@@ -19,7 +19,7 @@
/// When a function returns `Pending`, the function *must* also
/// ensure that the current task is scheduled to be awoken when
/// progress can be made.
- #[cfg_attr(not(bootstrap), lang = "Pending")]
+ #[lang = "Pending"]
#[stable(feature = "futures_api", since = "1.36.0")]
Pending,
}
@@ -112,6 +112,14 @@
#[stable(feature = "futures_api", since = "1.36.0")]
impl<T> From<T> for Poll<T> {
+ /// Convert to a `Ready` variant.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use core::task::Poll;
+ /// assert_eq!(Poll::from(true), Poll::Ready(true));
+ /// ```
fn from(t: T) -> Poll<T> {
Poll::Ready(t)
}
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index d4e733e..e221aaf3 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -5,7 +5,6 @@
/// # Examples
///
/// ```
-/// #![feature(future_readiness_fns)]
/// #![feature(ready_macro)]
///
/// use core::task::{ready, Context, Poll};
@@ -27,7 +26,6 @@
/// The `ready!` call expands to:
///
/// ```
-/// # #![feature(future_readiness_fns)]
/// # #![feature(ready_macro)]
/// #
/// # use core::task::{Context, Poll};
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 9205720..ba3fb35 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -8,10 +8,8 @@
///
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
///
-/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
-/// customizes the behavior of the `RawWaker`.
-///
-/// [`Waker`]: struct.Waker.html
+/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
+/// that customizes the behavior of the `RawWaker`.
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
@@ -52,12 +50,10 @@
/// The pointer passed to all functions inside the vtable is the `data` pointer
/// from the enclosing [`RawWaker`] object.
///
-/// The functions inside this struct are only intended be called on the `data`
+/// The functions inside this struct are only intended to be called on the `data`
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
-///
-/// [`RawWaker`]: struct.RawWaker.html
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
@@ -68,9 +64,6 @@
/// required for this additional instance of a [`RawWaker`] and associated
/// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
/// of the same task that would have been awoken by the original [`RawWaker`].
- ///
- /// [`Waker`]: struct.Waker.html
- /// [`RawWaker`]: struct.RawWaker.html
clone: unsafe fn(*const ()) -> RawWaker,
/// This function will be called when `wake` is called on the [`Waker`].
@@ -79,9 +72,6 @@
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
- ///
- /// [`Waker`]: struct.Waker.html
- /// [`RawWaker`]: struct.RawWaker.html
wake: unsafe fn(*const ()),
/// This function will be called when `wake_by_ref` is called on the [`Waker`].
@@ -89,9 +79,6 @@
///
/// This function is similar to `wake`, but must not consume the provided data
/// pointer.
- ///
- /// [`Waker`]: struct.Waker.html
- /// [`RawWaker`]: struct.RawWaker.html
wake_by_ref: unsafe fn(*const ()),
/// This function gets called when a [`RawWaker`] gets dropped.
@@ -99,8 +86,6 @@
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
- ///
- /// [`RawWaker`]: struct.RawWaker.html
drop: unsafe fn(*const ()),
}
@@ -142,18 +127,11 @@
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
- ///
- /// [`Waker`]: struct.Waker.html
- /// [`RawWaker`]: struct.RawWaker.html
#[rustc_promotable]
#[stable(feature = "futures_api", since = "1.36.0")]
- // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
- // without first consulting with T-Lang.
- //
- // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
- // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
- #[rustc_allow_const_fn_ptr]
#[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
+ #[cfg_attr(not(bootstrap), allow_internal_unstable(const_fn_fn_ptr_basics))]
+ #[cfg_attr(bootstrap, rustc_allow_const_fn_ptr)]
pub const fn new(
clone: unsafe fn(*const ()) -> RawWaker,
wake: unsafe fn(*const ()),
@@ -208,8 +186,6 @@
/// executor-specific wakeup behavior.
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
-///
-/// [`RawWaker`]: struct.RawWaker.html
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
@@ -275,9 +251,6 @@
/// The behavior of the returned `Waker` is undefined if the contract defined
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
/// Therefore this method is unsafe.
- ///
- /// [`RawWaker`]: struct.RawWaker.html
- /// [`RawWakerVTable`]: struct.RawWakerVTable.html
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 5741f8a..6dc542d 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -108,6 +108,34 @@
#[unstable(feature = "duration_constants", issue = "57391")]
pub const NANOSECOND: Duration = Duration::from_nanos(1);
+ /// The minimum duration.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(duration_constants)]
+ /// use std::time::Duration;
+ ///
+ /// assert_eq!(Duration::MIN, Duration::new(0, 0));
+ /// ```
+ #[unstable(feature = "duration_constants", issue = "57391")]
+ pub const MIN: Duration = Duration::from_nanos(0);
+
+ /// The maximum duration.
+ ///
+ /// It is roughly equal to a duration of 584,942,417,355 years.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(duration_constants)]
+ /// use std::time::Duration;
+ ///
+ /// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
+ /// ```
+ #[unstable(feature = "duration_constants", issue = "57391")]
+ pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
+
/// Creates a new `Duration` from the specified number of whole seconds and
/// additional nanoseconds.
///
@@ -450,6 +478,29 @@
}
}
+ /// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
+ /// if overflow occurred.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(duration_saturating_ops)]
+ /// #![feature(duration_constants)]
+ /// use std::time::Duration;
+ ///
+ /// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
+ /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
+ /// ```
+ #[unstable(feature = "duration_saturating_ops", issue = "76416")]
+ #[inline]
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn saturating_add(self, rhs: Duration) -> Duration {
+ match self.checked_add(rhs) {
+ Some(res) => res,
+ None => Duration::MAX,
+ }
+ }
+
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
/// if the result would be negative or if overflow occurred.
///
@@ -485,6 +536,29 @@
}
}
+ /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::MIN`]
+ /// if the result would be negative or if overflow occurred.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(duration_saturating_ops)]
+ /// #![feature(duration_constants)]
+ /// use std::time::Duration;
+ ///
+ /// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1));
+ /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::MIN);
+ /// ```
+ #[unstable(feature = "duration_saturating_ops", issue = "76416")]
+ #[inline]
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn saturating_sub(self, rhs: Duration) -> Duration {
+ match self.checked_sub(rhs) {
+ Some(res) => res,
+ None => Duration::MIN,
+ }
+ }
+
/// Checked `Duration` multiplication. Computes `self * other`, returning
/// [`None`] if overflow occurred.
///
@@ -515,6 +589,29 @@
None
}
+ /// Saturating `Duration` multiplication. Computes `self * other`, returning
+ /// [`Duration::MAX`] if overflow occurred.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(duration_saturating_ops)]
+ /// #![feature(duration_constants)]
+ /// use std::time::Duration;
+ ///
+ /// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
+ /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
+ /// ```
+ #[unstable(feature = "duration_saturating_ops", issue = "76416")]
+ #[inline]
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn saturating_mul(self, rhs: u32) -> Duration {
+ match self.checked_mul(rhs) {
+ Some(res) => res,
+ None => Duration::MAX,
+ }
+ }
+
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
/// if `other == 0`.
///
@@ -596,7 +693,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn from_secs_f64(secs: f64) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn from_secs_f64(secs: f64) -> Duration {
const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
let nanos = secs * (NANOS_PER_SEC as f64);
if !nanos.is_finite() {
@@ -630,7 +728,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn from_secs_f32(secs: f32) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn from_secs_f32(secs: f32) -> Duration {
const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
let nanos = secs * (NANOS_PER_SEC as f32);
if !nanos.is_finite() {
@@ -664,7 +763,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn mul_f64(self, rhs: f64) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn mul_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(rhs * self.as_secs_f64())
}
@@ -685,7 +785,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn mul_f32(self, rhs: f32) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn mul_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(rhs * self.as_secs_f32())
}
@@ -705,7 +806,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn div_f64(self, rhs: f64) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn div_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(self.as_secs_f64() / rhs)
}
@@ -727,7 +829,8 @@
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
- pub fn div_f32(self, rhs: f32) -> Duration {
+ #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+ pub const fn div_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(self.as_secs_f32() / rhs)
}