Format libcore with rustfmt
This commit applies rustfmt with default settings to files in src/libcore *that are not involved in any currently open PR* to minimize merge conflicts. The list of files involved in open PRs was determined by querying GitHub's GraphQL API with this script: https://gist.github.com/dtolnay/aa9c34993dc051a4f344d1b10e4487e8 With the list of files from the script in `outstanding_files`, the relevant commands were: $ find src/libcore -name '*.rs' | xargs rustfmt --edition=2018 $ rg libcore outstanding_files | xargs git checkout -- Repeating this process several months apart should get us coverage of most of the rest of libcore.
This commit is contained in:
parent
809e180a76
commit
95e00bfed8
52 changed files with 1801 additions and 1295 deletions
|
@ -12,8 +12,8 @@
|
|||
#![stable(feature = "core_ascii", since = "1.26.0")]
|
||||
|
||||
use crate::fmt;
|
||||
use crate::ops::Range;
|
||||
use crate::iter::FusedIterator;
|
||||
use crate::ops::Range;
|
||||
use crate::str::from_utf8_unchecked;
|
||||
|
||||
/// An iterator over the escaped version of a byte.
|
||||
|
@ -117,9 +117,15 @@ pub fn escape_default(c: u8) -> EscapeDefault {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Iterator for EscapeDefault {
|
||||
type Item = u8;
|
||||
fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
|
||||
fn last(mut self) -> Option<u8> { self.next_back() }
|
||||
fn next(&mut self) -> Option<u8> {
|
||||
self.range.next().map(|i| self.data[i])
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.range.size_hint()
|
||||
}
|
||||
fn last(mut self) -> Option<u8> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl DoubleEndedIterator for EscapeDefault {
|
||||
|
|
|
@ -158,7 +158,6 @@ impl From<u8> for char {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// An error which can be returned when parsing a char.
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -167,16 +166,16 @@ pub struct ParseCharError {
|
|||
}
|
||||
|
||||
impl ParseCharError {
|
||||
#[unstable(feature = "char_error_internals",
|
||||
#[unstable(
|
||||
feature = "char_error_internals",
|
||||
reason = "this method should not be available publicly",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn __description(&self) -> &str {
|
||||
match self.kind {
|
||||
CharErrorKind::EmptyString => {
|
||||
"cannot parse char from empty string"
|
||||
},
|
||||
CharErrorKind::TooManyChars => "too many characters in string"
|
||||
CharErrorKind::EmptyString => "cannot parse char from empty string",
|
||||
CharErrorKind::TooManyChars => "too many characters in string",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +193,6 @@ impl fmt::Display for ParseCharError {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
impl FromStr for char {
|
||||
type Err = ParseCharError;
|
||||
|
@ -203,17 +201,12 @@ impl FromStr for char {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut chars = s.chars();
|
||||
match (chars.next(), chars.next()) {
|
||||
(None, _) => {
|
||||
Err(ParseCharError { kind: CharErrorKind::EmptyString })
|
||||
},
|
||||
(None, _) => Err(ParseCharError { kind: CharErrorKind::EmptyString }),
|
||||
(Some(c), None) => Ok(c),
|
||||
_ => {
|
||||
Err(ParseCharError { kind: CharErrorKind::TooManyChars })
|
||||
_ => Err(ParseCharError { kind: CharErrorKind::TooManyChars }),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
impl TryFrom<u32> for char {
|
||||
|
@ -304,11 +297,7 @@ pub fn from_digit(num: u32, radix: u32) -> Option<char> {
|
|||
}
|
||||
if num < radix {
|
||||
let num = num as u8;
|
||||
if num < 10 {
|
||||
Some((b'0' + num) as char)
|
||||
} else {
|
||||
Some((b'a' + num - 10) as char)
|
||||
}
|
||||
if num < 10 { Some((b'0' + num) as char) } else { Some((b'a' + num - 10) as char) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ use super::from_u32_unchecked;
|
|||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DecodeUtf16<I>
|
||||
where I: Iterator<Item = u16>
|
||||
where
|
||||
I: Iterator<Item = u16>,
|
||||
{
|
||||
iter: I,
|
||||
buf: Option<u16>,
|
||||
|
@ -70,10 +71,7 @@ pub struct DecodeUtf16Error {
|
|||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||
#[inline]
|
||||
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
|
||||
DecodeUtf16 {
|
||||
iter: iter.into_iter(),
|
||||
buf: None,
|
||||
}
|
||||
DecodeUtf16 { iter: iter.into_iter(), buf: None }
|
||||
}
|
||||
|
||||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||
|
@ -83,7 +81,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
|
|||
fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
|
||||
let u = match self.buf.take() {
|
||||
Some(buf) => buf,
|
||||
None => self.iter.next()?
|
||||
None => self.iter.next()?,
|
||||
};
|
||||
|
||||
if u < 0xD800 || 0xDFFF < u {
|
||||
|
|
|
@ -130,11 +130,7 @@ impl char {
|
|||
}
|
||||
};
|
||||
|
||||
if val < radix {
|
||||
Some(val)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if val < radix { Some(val) } else { None }
|
||||
}
|
||||
|
||||
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
||||
|
@ -950,11 +946,7 @@ impl char {
|
|||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
#[inline]
|
||||
pub fn to_ascii_uppercase(&self) -> char {
|
||||
if self.is_ascii() {
|
||||
(*self as u8).to_ascii_uppercase() as char
|
||||
} else {
|
||||
*self
|
||||
}
|
||||
if self.is_ascii() { (*self as u8).to_ascii_uppercase() as char } else { *self }
|
||||
}
|
||||
|
||||
/// Makes a copy of the value in its ASCII lower case equivalent.
|
||||
|
@ -982,11 +974,7 @@ impl char {
|
|||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
#[inline]
|
||||
pub fn to_ascii_lowercase(&self) -> char {
|
||||
if self.is_ascii() {
|
||||
(*self as u8).to_ascii_lowercase() as char
|
||||
} else {
|
||||
*self
|
||||
}
|
||||
if self.is_ascii() { (*self as u8).to_ascii_lowercase() as char } else { *self }
|
||||
}
|
||||
|
||||
/// Checks that two values are an ASCII case-insensitive match.
|
||||
|
|
|
@ -24,14 +24,14 @@ mod decode;
|
|||
mod methods;
|
||||
|
||||
// stable re-exports
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::convert::{from_u32, from_digit};
|
||||
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
||||
pub use self::convert::from_u32_unchecked;
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
pub use self::convert::ParseCharError;
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub use self::convert::CharTryFromError;
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
pub use self::convert::ParseCharError;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::convert::{from_digit, from_u32};
|
||||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
|
||||
|
||||
|
@ -190,11 +190,11 @@ impl Iterator for EscapeUnicode {
|
|||
match self.state {
|
||||
EscapeUnicodeState::Done => None,
|
||||
|
||||
EscapeUnicodeState::RightBrace |
|
||||
EscapeUnicodeState::Value |
|
||||
EscapeUnicodeState::LeftBrace |
|
||||
EscapeUnicodeState::Type |
|
||||
EscapeUnicodeState::Backslash => Some('}'),
|
||||
EscapeUnicodeState::RightBrace
|
||||
| EscapeUnicodeState::Value
|
||||
| EscapeUnicodeState::LeftBrace
|
||||
| EscapeUnicodeState::Type
|
||||
| EscapeUnicodeState::Backslash => Some('}'),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +204,8 @@ impl ExactSizeIterator for EscapeUnicode {
|
|||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
// The match is a single memory access with no branching
|
||||
self.hex_digit_idx + match self.state {
|
||||
self.hex_digit_idx
|
||||
+ match self.state {
|
||||
EscapeUnicodeState::Done => 0,
|
||||
EscapeUnicodeState::RightBrace => 1,
|
||||
EscapeUnicodeState::Value => 2,
|
||||
|
@ -238,7 +239,7 @@ impl fmt::Display for EscapeUnicode {
|
|||
#[derive(Clone, Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct EscapeDefault {
|
||||
state: EscapeDefaultState
|
||||
state: EscapeDefaultState,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -284,24 +285,20 @@ impl Iterator for EscapeDefault {
|
|||
EscapeDefaultState::Backslash(c) if n == 0 => {
|
||||
self.state = EscapeDefaultState::Char(c);
|
||||
Some('\\')
|
||||
},
|
||||
}
|
||||
EscapeDefaultState::Backslash(c) if n == 1 => {
|
||||
self.state = EscapeDefaultState::Done;
|
||||
Some(c)
|
||||
},
|
||||
}
|
||||
EscapeDefaultState::Backslash(_) => {
|
||||
self.state = EscapeDefaultState::Done;
|
||||
None
|
||||
},
|
||||
}
|
||||
EscapeDefaultState::Char(c) => {
|
||||
self.state = EscapeDefaultState::Done;
|
||||
|
||||
if n == 0 {
|
||||
Some(c)
|
||||
} else {
|
||||
None
|
||||
if n == 0 { Some(c) } else { None }
|
||||
}
|
||||
},
|
||||
EscapeDefaultState::Done => None,
|
||||
EscapeDefaultState::Unicode(ref mut i) => i.nth(n),
|
||||
}
|
||||
|
@ -355,8 +352,12 @@ pub struct EscapeDebug(EscapeDefault);
|
|||
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
||||
impl Iterator for EscapeDebug {
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<char> { self.0.next() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
|
||||
fn next(&mut self) -> Option<char> {
|
||||
self.0.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
||||
|
@ -493,9 +494,7 @@ impl fmt::Display for CaseMappingIter {
|
|||
f.write_char(b)?;
|
||||
f.write_char(c)
|
||||
}
|
||||
CaseMappingIter::One(c) => {
|
||||
f.write_char(c)
|
||||
}
|
||||
CaseMappingIter::One(c) => f.write_char(c),
|
||||
CaseMappingIter::Zero => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,9 @@ pub trait Clone : Sized {
|
|||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
|
||||
pub macro Clone($item:item) { /* compiler built-in */ }
|
||||
pub macro Clone($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
// FIXME(aburka): these structs are used solely by #[derive] to
|
||||
// assert that every component of a type implements Clone or Copy.
|
||||
|
@ -145,16 +147,24 @@ pub macro Clone($item:item) { /* compiler built-in */ }
|
|||
// These structs should never appear in user code.
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "derive_clone_copy",
|
||||
#[unstable(
|
||||
feature = "derive_clone_copy",
|
||||
reason = "deriving hack, should not be public",
|
||||
issue = "0")]
|
||||
pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: crate::marker::PhantomData<T> }
|
||||
issue = "0"
|
||||
)]
|
||||
pub struct AssertParamIsClone<T: Clone + ?Sized> {
|
||||
_field: crate::marker::PhantomData<T>,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "derive_clone_copy",
|
||||
#[unstable(
|
||||
feature = "derive_clone_copy",
|
||||
reason = "deriving hack, should not be public",
|
||||
issue = "0")]
|
||||
pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: crate::marker::PhantomData<T> }
|
||||
issue = "0"
|
||||
)]
|
||||
pub struct AssertParamIsCopy<T: Copy + ?Sized> {
|
||||
_field: crate::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
/// Implementations of `Clone` for primitive types.
|
||||
///
|
||||
|
@ -217,5 +227,4 @@ mod impls {
|
|||
*self
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,7 +95,9 @@
|
|||
/// ```
|
||||
#[stable(feature = "convert_id", since = "1.33.0")]
|
||||
#[inline]
|
||||
pub const fn identity<T>(x: T) -> T { x }
|
||||
pub const fn identity<T>(x: T) -> T {
|
||||
x
|
||||
}
|
||||
|
||||
/// Used to do a cheap reference-to-reference conversion.
|
||||
///
|
||||
|
@ -364,12 +366,10 @@ pub trait Into<T>: Sized {
|
|||
/// [`from`]: trait.From.html#tymethod.from
|
||||
/// [book]: ../../book/ch09-00-error-handling.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(
|
||||
on(
|
||||
#[rustc_on_unimplemented(on(
|
||||
all(_Self = "&str", T = "std::string::String"),
|
||||
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
|
||||
)
|
||||
)]
|
||||
))]
|
||||
pub trait From<T>: Sized {
|
||||
/// Performs the conversion.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -490,7 +490,9 @@ pub trait TryFrom<T>: Sized {
|
|||
|
||||
// As lifts over &
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where T: AsRef<U>
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &T
|
||||
where
|
||||
T: AsRef<U>,
|
||||
{
|
||||
fn as_ref(&self) -> &U {
|
||||
<T as AsRef<U>>::as_ref(*self)
|
||||
|
@ -499,7 +501,9 @@ impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where T: AsRef<U>
|
|||
|
||||
// As lifts over &mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where T: AsRef<U>
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T
|
||||
where
|
||||
T: AsRef<U>,
|
||||
{
|
||||
fn as_ref(&self) -> &U {
|
||||
<T as AsRef<U>>::as_ref(*self)
|
||||
|
@ -516,7 +520,9 @@ impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where T: AsRef<U>
|
|||
|
||||
// AsMut lifts over &mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where T: AsMut<U>
|
||||
impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T
|
||||
where
|
||||
T: AsMut<U>,
|
||||
{
|
||||
fn as_mut(&mut self) -> &mut U {
|
||||
(*self).as_mut()
|
||||
|
@ -533,7 +539,9 @@ impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where T: AsMut<U>
|
|||
|
||||
// From implies Into
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, U> Into<U> for T where U: From<T>
|
||||
impl<T, U> Into<U> for T
|
||||
where
|
||||
U: From<T>,
|
||||
{
|
||||
fn into(self) -> U {
|
||||
U::from(self)
|
||||
|
@ -543,7 +551,9 @@ impl<T, U> Into<U> for T where U: From<T>
|
|||
// From (and thus Into) is reflexive
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> From<T> for T {
|
||||
fn from(t: T) -> T { t }
|
||||
fn from(t: T) -> T {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
/// **Stability note:** This impl does not yet exist, but we are
|
||||
|
@ -555,12 +565,16 @@ impl<T> From<T> for T {
|
|||
#[rustc_reservation_impl = "permitting this impl would forbid us from adding \
|
||||
`impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
|
||||
impl<T> From<!> for T {
|
||||
fn from(t: !) -> T { t }
|
||||
fn from(t: !) -> T {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
// TryFrom implies TryInto
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
impl<T, U> TryInto<U> for T where U: TryFrom<T>
|
||||
impl<T, U> TryInto<U> for T
|
||||
where
|
||||
U: TryFrom<T>,
|
||||
{
|
||||
type Error = U::Error;
|
||||
|
||||
|
@ -572,7 +586,10 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
|
|||
// Infallible conversions are semantically equivalent to fallible conversions
|
||||
// with an uninhabited error type.
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
impl<T, U> TryFrom<U> for T where U: Into<T> {
|
||||
impl<T, U> TryFrom<U> for T
|
||||
where
|
||||
U: Into<T>,
|
||||
{
|
||||
type Error = Infallible;
|
||||
|
||||
fn try_from(value: U) -> Result<Self, Self::Error> {
|
||||
|
|
|
@ -119,7 +119,9 @@ pub trait Default: Sized {
|
|||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Default($item:item) { /* compiler built-in */ }
|
||||
pub macro Default($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
macro_rules! default_impl {
|
||||
($t:ty, $v:expr, $doc:tt) => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![stable(feature = "", since = "1.30.0")]
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
//! Utilities related to FFI bindings.
|
||||
|
@ -36,12 +35,20 @@ use crate::ops::{Deref, DerefMut};
|
|||
#[repr(u8)]
|
||||
#[stable(feature = "core_c_void", since = "1.30.0")]
|
||||
pub enum c_void {
|
||||
#[unstable(feature = "c_void_variant", reason = "temporary implementation detail",
|
||||
issue = "0")]
|
||||
#[doc(hidden)] __variant1,
|
||||
#[unstable(feature = "c_void_variant", reason = "temporary implementation detail",
|
||||
issue = "0")]
|
||||
#[doc(hidden)] __variant2,
|
||||
#[unstable(
|
||||
feature = "c_void_variant",
|
||||
reason = "temporary implementation detail",
|
||||
issue = "0"
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
__variant1,
|
||||
#[unstable(
|
||||
feature = "c_void_variant",
|
||||
reason = "temporary implementation detail",
|
||||
issue = "0"
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
__variant2,
|
||||
}
|
||||
|
||||
#[stable(feature = "std_debug", since = "1.16.0")]
|
||||
|
@ -53,17 +60,20 @@ impl fmt::Debug for c_void {
|
|||
|
||||
/// Basic implementation of a `va_list`.
|
||||
// The name is WIP, using `VaListImpl` for now.
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
#[cfg(any(
|
||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
target_arch = "wasm32",
|
||||
target_arch = "asmjs",
|
||||
windows))]
|
||||
windows
|
||||
))]
|
||||
#[repr(transparent)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
ptr: *mut c_void,
|
||||
|
@ -73,16 +83,19 @@ pub struct VaListImpl<'f> {
|
|||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
#[cfg(any(
|
||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
target_arch = "wasm32",
|
||||
target_arch = "asmjs",
|
||||
windows))]
|
||||
#[unstable(feature = "c_variadic",
|
||||
windows
|
||||
))]
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> fmt::Debug for VaListImpl<'f> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "va_list* {:p}", self.ptr)
|
||||
|
@ -97,10 +110,12 @@ impl<'f> fmt::Debug for VaListImpl<'f> {
|
|||
#[cfg(all(target_arch = "aarch64", not(target_os = "ios"), not(windows)))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
stack: *mut c_void,
|
||||
|
@ -115,10 +130,12 @@ pub struct VaListImpl<'f> {
|
|||
#[cfg(all(target_arch = "powerpc", not(windows)))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gpr: u8,
|
||||
|
@ -133,10 +150,12 @@ pub struct VaListImpl<'f> {
|
|||
#[cfg(all(target_arch = "x86_64", not(windows)))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gp_offset: i32,
|
||||
|
@ -149,76 +168,86 @@ pub struct VaListImpl<'f> {
|
|||
/// A wrapper for a `va_list`
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
pub struct VaList<'a, 'f: 'a> {
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
#[cfg(any(
|
||||
all(
|
||||
not(target_arch = "aarch64"),
|
||||
not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")
|
||||
),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
target_arch = "wasm32",
|
||||
target_arch = "asmjs",
|
||||
windows))]
|
||||
windows
|
||||
))]
|
||||
inner: VaListImpl<'f>,
|
||||
|
||||
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
|
||||
target_arch = "x86_64"),
|
||||
#[cfg(all(
|
||||
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||
any(not(target_arch = "aarch64"), not(target_os = "ios")),
|
||||
not(target_arch = "wasm32"),
|
||||
not(target_arch = "asmjs"),
|
||||
not(windows)))]
|
||||
not(windows)
|
||||
))]
|
||||
inner: &'a mut VaListImpl<'f>,
|
||||
|
||||
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||
}
|
||||
|
||||
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
|
||||
not(target_arch = "x86_64")),
|
||||
#[cfg(any(
|
||||
all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")),
|
||||
all(target_arch = "aarch64", target_os = "ios"),
|
||||
target_arch = "wasm32",
|
||||
target_arch = "asmjs",
|
||||
windows))]
|
||||
#[unstable(feature = "c_variadic",
|
||||
windows
|
||||
))]
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList {
|
||||
inner: VaListImpl { ..*self },
|
||||
_marker: PhantomData,
|
||||
}
|
||||
VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
|
||||
target_arch = "x86_64"),
|
||||
#[cfg(all(
|
||||
any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
|
||||
any(not(target_arch = "aarch64"), not(target_os = "ios")),
|
||||
not(target_arch = "wasm32"),
|
||||
not(target_arch = "asmjs"),
|
||||
not(windows)))]
|
||||
#[unstable(feature = "c_variadic",
|
||||
not(windows)
|
||||
))]
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList {
|
||||
inner: self,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
VaList { inner: self, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'a, 'f: 'a> Deref for VaList<'a, 'f> {
|
||||
type Target = VaListImpl<'f>;
|
||||
|
||||
|
@ -228,10 +257,12 @@ impl<'a, 'f: 'a> Deref for VaList<'a, 'f> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut VaListImpl<'f> {
|
||||
|
@ -252,10 +283,12 @@ mod sealed_trait {
|
|||
/// Trait which whitelists the allowed types to be used with [VaList::arg]
|
||||
///
|
||||
/// [VaList::va_arg]: struct.VaList.html#method.arg
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
pub trait VaArgSafe {}
|
||||
}
|
||||
|
||||
|
@ -275,21 +308,27 @@ impl_va_arg_safe!{i8, i16, i32, i64, usize}
|
|||
impl_va_arg_safe! {u8, u16, u32, u64, isize}
|
||||
impl_va_arg_safe! {f64}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<T> sealed_trait::VaArgSafe for *mut T {}
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<T> sealed_trait::VaArgSafe for *const T {}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Advance to the next arg.
|
||||
#[inline]
|
||||
|
@ -299,7 +338,9 @@ impl<'f> VaListImpl<'f> {
|
|||
|
||||
/// Copies the `va_list` at the current location.
|
||||
pub unsafe fn with_copy<F, R>(&self, f: F) -> R
|
||||
where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R {
|
||||
where
|
||||
F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R,
|
||||
{
|
||||
let mut ap = self.clone();
|
||||
let ret = f(ap.as_va_list());
|
||||
va_end(&mut ap);
|
||||
|
@ -307,10 +348,12 @@ impl<'f> VaListImpl<'f> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> Clone for VaListImpl<'f> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
|
@ -323,10 +366,12 @@ impl<'f> Clone for VaListImpl<'f> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "c_variadic",
|
||||
#[unstable(
|
||||
feature = "c_variadic",
|
||||
reason = "the `c_variadic` feature has not been properly tested on \
|
||||
all supported platforms",
|
||||
issue = "44930")]
|
||||
issue = "44930"
|
||||
)]
|
||||
impl<'f> Drop for VaListImpl<'f> {
|
||||
fn drop(&mut self) {
|
||||
// FIXME: this should call `va_end`, but there's no clean way to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
|
||||
use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::num::flt2dec;
|
||||
|
||||
|
@ -7,9 +7,14 @@ use crate::num::flt2dec;
|
|||
// Don't inline this so callers don't use the stack space this function
|
||||
// requires unless they have to.
|
||||
#[inline(never)]
|
||||
fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
|
||||
sign: flt2dec::Sign, precision: usize) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
fn float_to_decimal_common_exact<T>(
|
||||
fmt: &mut Formatter<'_>,
|
||||
num: &T,
|
||||
sign: flt2dec::Sign,
|
||||
precision: usize,
|
||||
) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
unsafe {
|
||||
let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
|
||||
|
@ -19,9 +24,15 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
|
|||
// 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,
|
||||
false, buf.get_mut(), parts.get_mut());
|
||||
let formatted = flt2dec::to_exact_fixed_str(
|
||||
flt2dec::strategy::grisu::format_exact,
|
||||
*num,
|
||||
sign,
|
||||
precision,
|
||||
false,
|
||||
buf.get_mut(),
|
||||
parts.get_mut(),
|
||||
);
|
||||
fmt.pad_formatted_parts(&formatted)
|
||||
}
|
||||
}
|
||||
|
@ -29,26 +40,42 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
|
|||
// Don't inline this so callers that call both this and the above won't wind
|
||||
// up using the combined stack space of both functions in some cases.
|
||||
#[inline(never)]
|
||||
fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter<'_>, num: &T,
|
||||
sign: flt2dec::Sign, precision: usize) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
fn float_to_decimal_common_shortest<T>(
|
||||
fmt: &mut Formatter<'_>,
|
||||
num: &T,
|
||||
sign: flt2dec::Sign,
|
||||
precision: usize,
|
||||
) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
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, false, buf.get_mut(),
|
||||
parts.get_mut());
|
||||
let formatted = flt2dec::to_shortest_str(
|
||||
flt2dec::strategy::grisu::format_shortest,
|
||||
*num,
|
||||
sign,
|
||||
precision,
|
||||
false,
|
||||
buf.get_mut(),
|
||||
parts.get_mut(),
|
||||
);
|
||||
fmt.pad_formatted_parts(&formatted)
|
||||
}
|
||||
}
|
||||
|
||||
// Common code of floating point Debug and Display.
|
||||
fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T,
|
||||
negative_zero: bool, min_precision: usize) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
fn float_to_decimal_common<T>(
|
||||
fmt: &mut Formatter<'_>,
|
||||
num: &T,
|
||||
negative_zero: bool,
|
||||
min_precision: usize,
|
||||
) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
let force_sign = fmt.sign_plus();
|
||||
let sign = match (force_sign, negative_zero) {
|
||||
|
@ -68,18 +95,29 @@ fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T,
|
|||
// Don't inline this so callers don't use the stack space this function
|
||||
// requires unless they have to.
|
||||
#[inline(never)]
|
||||
fn float_to_exponential_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
|
||||
sign: flt2dec::Sign, precision: usize,
|
||||
upper: bool) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
fn float_to_exponential_common_exact<T>(
|
||||
fmt: &mut Formatter<'_>,
|
||||
num: &T,
|
||||
sign: flt2dec::Sign,
|
||||
precision: usize,
|
||||
upper: bool,
|
||||
) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
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());
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -87,26 +125,37 @@ fn float_to_exponential_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
|
|||
// Don't inline this so callers that call both this and the above won't wind
|
||||
// up using the combined stack space of both functions in some cases.
|
||||
#[inline(never)]
|
||||
fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter<'_>,
|
||||
num: &T, sign: flt2dec::Sign,
|
||||
upper: bool) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
fn float_to_exponential_common_shortest<T>(
|
||||
fmt: &mut Formatter<'_>,
|
||||
num: &T,
|
||||
sign: flt2dec::Sign,
|
||||
upper: bool,
|
||||
) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
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());
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// Common code of floating point LowerExp and UpperExp.
|
||||
fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result
|
||||
where T: flt2dec::DecodableFloat
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
let force_sign = fmt.sign_plus();
|
||||
let sign = match force_sign {
|
||||
|
@ -123,7 +172,7 @@ fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool)
|
|||
}
|
||||
|
||||
macro_rules! floating {
|
||||
($ty:ident) => (
|
||||
($ty:ident) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Debug for $ty {
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
|
||||
|
@ -151,7 +200,7 @@ macro_rules! floating {
|
|||
float_to_exponential_common(fmt, self, true)
|
||||
}
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
floating! { f32 }
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::cell::{UnsafeCell, Cell, RefCell, Ref, RefMut};
|
||||
use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
|
||||
use crate::marker::PhantomData;
|
||||
use crate::mem;
|
||||
use crate::num::flt2dec;
|
||||
|
@ -13,9 +13,9 @@ use crate::result;
|
|||
use crate::slice;
|
||||
use crate::str;
|
||||
|
||||
mod builders;
|
||||
mod float;
|
||||
mod num;
|
||||
mod builders;
|
||||
|
||||
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
|
||||
/// Possible alignments returned by `Formatter::align`
|
||||
|
@ -33,10 +33,9 @@ pub enum Alignment {
|
|||
}
|
||||
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
|
||||
pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
#[doc(hidden)]
|
||||
pub mod rt {
|
||||
pub mod v1;
|
||||
|
@ -260,8 +259,7 @@ struct Void {
|
|||
/// types, and then this struct is used to canonicalize arguments to one type.
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
#[doc(hidden)]
|
||||
pub struct ArgumentV1<'a> {
|
||||
value: &'a Void,
|
||||
|
@ -275,21 +273,13 @@ impl<'a> ArgumentV1<'a> {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
pub fn new<'b, T>(x: &'b T,
|
||||
f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
|
||||
unsafe {
|
||||
ArgumentV1 {
|
||||
formatter: mem::transmute(f),
|
||||
value: mem::transmute(x)
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
|
||||
unsafe { ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
|
||||
ArgumentV1::new(x, ArgumentV1::show_usize)
|
||||
}
|
||||
|
@ -305,21 +295,23 @@ impl<'a> ArgumentV1<'a> {
|
|||
|
||||
// flags available in the v1 format of format_args
|
||||
#[derive(Copy, Clone)]
|
||||
enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, DebugLowerHex, DebugUpperHex }
|
||||
enum FlagV1 {
|
||||
SignPlus,
|
||||
SignMinus,
|
||||
Alternate,
|
||||
SignAwareZeroPad,
|
||||
DebugLowerHex,
|
||||
DebugUpperHex,
|
||||
}
|
||||
|
||||
impl<'a> Arguments<'a> {
|
||||
/// When using the format_args!() macro, this function is used to generate the
|
||||
/// Arguments structure.
|
||||
#[doc(hidden)] #[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
pub fn new_v1(pieces: &'a [&'a str],
|
||||
args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
|
||||
Arguments {
|
||||
pieces,
|
||||
fmt: None,
|
||||
args,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
pub fn new_v1(pieces: &'a [&'a str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
|
||||
Arguments { pieces, fmt: None, args }
|
||||
}
|
||||
|
||||
/// This function is used to specify nonstandard formatting parameters.
|
||||
|
@ -328,29 +320,26 @@ impl<'a> Arguments<'a> {
|
|||
/// `CountIsParam` or `CountIsNextParam` has to point to an argument
|
||||
/// created with `argumentusize`. However, failing to do so doesn't cause
|
||||
/// unsafety, but will ignore invalid .
|
||||
#[doc(hidden)] #[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
pub fn new_v1_formatted(pieces: &'a [&'a str],
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
pub fn new_v1_formatted(
|
||||
pieces: &'a [&'a str],
|
||||
args: &'a [ArgumentV1<'a>],
|
||||
fmt: &'a [rt::v1::Argument]) -> Arguments<'a> {
|
||||
Arguments {
|
||||
pieces,
|
||||
fmt: Some(fmt),
|
||||
args,
|
||||
}
|
||||
fmt: &'a [rt::v1::Argument],
|
||||
) -> Arguments<'a> {
|
||||
Arguments { pieces, fmt: Some(fmt), args }
|
||||
}
|
||||
|
||||
/// Estimates the length of the formatted text.
|
||||
///
|
||||
/// This is intended to be used for setting initial `String` capacity
|
||||
/// when using `format!`. Note: this is neither the lower nor upper bound.
|
||||
#[doc(hidden)] #[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
|
||||
issue = "0")]
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "0")]
|
||||
pub fn estimated_capacity(&self) -> usize {
|
||||
let pieces_length: usize = self.pieces.iter()
|
||||
.map(|x| x.len()).sum();
|
||||
let pieces_length: usize = self.pieces.iter().map(|x| x.len()).sum();
|
||||
|
||||
if self.args.is_empty() {
|
||||
pieces_length
|
||||
|
@ -514,10 +503,13 @@ impl Display for Arguments<'_> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(
|
||||
on(crate_local, label="`{Self}` cannot be formatted using `{{:?}}`",
|
||||
note="add `#[derive(Debug)]` or manually implement `{Debug}`"),
|
||||
on(
|
||||
crate_local,
|
||||
label = "`{Self}` cannot be formatted using `{{:?}}`",
|
||||
note = "add `#[derive(Debug)]` or manually implement `{Debug}`"
|
||||
),
|
||||
message = "`{Self}` doesn't implement `{Debug}`",
|
||||
label="`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`",
|
||||
label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`"
|
||||
)]
|
||||
#[doc(alias = "{:?}")]
|
||||
#[rustc_diagnostic_item = "debug_trait"]
|
||||
|
@ -553,7 +545,9 @@ pub(crate) mod macros {
|
|||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Debug($item:item) { /* compiler built-in */ }
|
||||
pub macro Debug($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
}
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[doc(inline)]
|
||||
|
@ -601,7 +595,7 @@ pub use macros::Debug;
|
|||
),
|
||||
message = "`{Self}` doesn't implement `{Display}`",
|
||||
label = "`{Self}` cannot be formatted with the default formatter",
|
||||
note="in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead",
|
||||
note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead"
|
||||
)]
|
||||
#[doc(alias = "{}")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1073,7 +1067,9 @@ impl PostPadding {
|
|||
|
||||
impl<'a> Formatter<'a> {
|
||||
fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c>
|
||||
where 'b: 'c, F: FnOnce(&'b mut (dyn Write+'b)) -> &'c mut (dyn Write+'c)
|
||||
where
|
||||
'b: 'c,
|
||||
F: FnOnce(&'b mut (dyn Write + 'b)) -> &'c mut (dyn Write + 'c),
|
||||
{
|
||||
Formatter {
|
||||
// We want to change this
|
||||
|
@ -1106,7 +1102,7 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
// Extract the correct argument
|
||||
let value = match arg.position {
|
||||
rt::v1::Position::Next => { *self.curarg.next().unwrap() }
|
||||
rt::v1::Position::Next => *self.curarg.next().unwrap(),
|
||||
rt::v1::Position::At(i) => self.args[i],
|
||||
};
|
||||
|
||||
|
@ -1118,12 +1114,8 @@ impl<'a> Formatter<'a> {
|
|||
match *cnt {
|
||||
rt::v1::Count::Is(n) => Some(n),
|
||||
rt::v1::Count::Implied => None,
|
||||
rt::v1::Count::Param(i) => {
|
||||
self.args[i].as_usize()
|
||||
}
|
||||
rt::v1::Count::NextParam => {
|
||||
self.curarg.next()?.as_usize()
|
||||
}
|
||||
rt::v1::Count::Param(i) => self.args[i].as_usize(),
|
||||
rt::v1::Count::NextParam => self.curarg.next()?.as_usize(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1174,18 +1166,16 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{:0>#8}", Foo::new(-1)), "00-Foo 1");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn pad_integral(&mut self,
|
||||
is_nonnegative: bool,
|
||||
prefix: &str,
|
||||
buf: &str)
|
||||
-> Result {
|
||||
pub fn pad_integral(&mut self, is_nonnegative: bool, prefix: &str, buf: &str) -> Result {
|
||||
let mut width = buf.len();
|
||||
|
||||
let mut sign = None;
|
||||
if !is_nonnegative {
|
||||
sign = Some('-'); width += 1;
|
||||
sign = Some('-');
|
||||
width += 1;
|
||||
} else if self.sign_plus() {
|
||||
sign = Some('+'); width += 1;
|
||||
sign = Some('+');
|
||||
width += 1;
|
||||
}
|
||||
|
||||
let prefix = if self.alternate() {
|
||||
|
@ -1201,11 +1191,7 @@ impl<'a> Formatter<'a> {
|
|||
if let Some(c) = sign {
|
||||
f.buf.write_char(c)?;
|
||||
}
|
||||
if let Some(prefix) = prefix {
|
||||
f.buf.write_str(prefix)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
if let Some(prefix) = prefix { f.buf.write_str(prefix) } else { Ok(()) }
|
||||
}
|
||||
|
||||
// The `width` field is more of a `min-width` parameter at this point.
|
||||
|
@ -1301,9 +1287,7 @@ impl<'a> Formatter<'a> {
|
|||
None => self.buf.write_str(s),
|
||||
// If we're under the maximum width, check if we're over the minimum
|
||||
// width, if so it's as easy as just emitting the string.
|
||||
Some(width) if s.chars().count() >= width => {
|
||||
self.buf.write_str(s)
|
||||
}
|
||||
Some(width) if s.chars().count() >= width => self.buf.write_str(s),
|
||||
// If we're under both the maximum and the minimum width, then fill
|
||||
// up the minimum width with the specified string + some alignment.
|
||||
Some(width) => {
|
||||
|
@ -1321,17 +1305,16 @@ impl<'a> Formatter<'a> {
|
|||
fn padding(
|
||||
&mut self,
|
||||
padding: usize,
|
||||
default: rt::v1::Alignment
|
||||
default: rt::v1::Alignment,
|
||||
) -> result::Result<PostPadding, Error> {
|
||||
let align = match self.align {
|
||||
rt::v1::Alignment::Unknown => default,
|
||||
_ => self.align
|
||||
_ => self.align,
|
||||
};
|
||||
|
||||
let (pre_pad, post_pad) = match align {
|
||||
rt::v1::Alignment::Left => (0, padding),
|
||||
rt::v1::Alignment::Right |
|
||||
rt::v1::Alignment::Unknown => (padding, 0),
|
||||
rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0),
|
||||
rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2),
|
||||
};
|
||||
|
||||
|
@ -1368,7 +1351,8 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
// remaining parts go through the ordinary padding process.
|
||||
let len = formatted.len();
|
||||
let ret = if width <= len { // no padding
|
||||
let ret = if width <= len {
|
||||
// no padding
|
||||
self.write_formatted_parts(&formatted)
|
||||
} else {
|
||||
let post_padding = self.padding(width - len, align)?;
|
||||
|
@ -1473,10 +1457,14 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
/// Flags for formatting
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.24.0",
|
||||
#[rustc_deprecated(
|
||||
since = "1.24.0",
|
||||
reason = "use the `sign_plus`, `sign_minus`, `alternate`, \
|
||||
or `sign_aware_zero_pad` methods instead")]
|
||||
pub fn flags(&self) -> u32 { self.flags }
|
||||
or `sign_aware_zero_pad` methods instead"
|
||||
)]
|
||||
pub fn flags(&self) -> u32 {
|
||||
self.flags
|
||||
}
|
||||
|
||||
/// Character used as 'fill' whenever there is alignment.
|
||||
///
|
||||
|
@ -1506,7 +1494,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{:t>6}", Foo), "tttttt");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn fill(&self) -> char { self.fill }
|
||||
pub fn fill(&self) -> char {
|
||||
self.fill
|
||||
}
|
||||
|
||||
/// Flag indicating what form of alignment was requested.
|
||||
///
|
||||
|
@ -1574,7 +1564,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn width(&self) -> Option<usize> { self.width }
|
||||
pub fn width(&self) -> Option<usize> {
|
||||
self.width
|
||||
}
|
||||
|
||||
/// Optionally specified precision for numeric types.
|
||||
///
|
||||
|
@ -1601,7 +1593,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{}", Foo(23.2)), "Foo(23.20)");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn precision(&self) -> Option<usize> { self.precision }
|
||||
pub fn precision(&self) -> Option<usize> {
|
||||
self.precision
|
||||
}
|
||||
|
||||
/// Determines if the `+` flag was specified.
|
||||
///
|
||||
|
@ -1629,7 +1623,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 }
|
||||
pub fn sign_plus(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::SignPlus as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `-` flag was specified.
|
||||
///
|
||||
|
@ -1655,7 +1651,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{}", Foo(23)), "Foo(23)");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 }
|
||||
pub fn sign_minus(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::SignMinus as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `#` flag was specified.
|
||||
///
|
||||
|
@ -1680,7 +1678,9 @@ impl<'a> Formatter<'a> {
|
|||
/// assert_eq!(&format!("{}", Foo(23)), "23");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 }
|
||||
pub fn alternate(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::Alternate as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `0` flag was specified.
|
||||
///
|
||||
|
@ -1709,9 +1709,13 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
// FIXME: Decide what public API we want for these two flags.
|
||||
// https://github.com/rust-lang/rust/issues/48584
|
||||
fn debug_lower_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 }
|
||||
fn debug_lower_hex(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0
|
||||
}
|
||||
|
||||
fn debug_upper_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 }
|
||||
fn debug_upper_hex(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0
|
||||
}
|
||||
|
||||
/// Creates a [`DebugStruct`] builder designed to assist with creation of
|
||||
/// [`fmt::Debug`] implementations for structs.
|
||||
|
@ -2067,11 +2071,15 @@ impl<T: ?Sized> Pointer for &mut T {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Debug for *const T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) }
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(self, f)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Debug for *mut T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) }
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! peel {
|
||||
|
@ -2129,9 +2137,7 @@ impl<T: ?Sized> Debug for PhantomData<T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Copy + Debug> Debug for Cell<T> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
f.debug_struct("Cell")
|
||||
.field("value", &self.get())
|
||||
.finish()
|
||||
f.debug_struct("Cell").field("value", &self.get()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2139,11 +2145,7 @@ impl<T: Copy + Debug> Debug for Cell<T> {
|
|||
impl<T: ?Sized + Debug> Debug for RefCell<T> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
match self.try_borrow() {
|
||||
Ok(borrow) => {
|
||||
f.debug_struct("RefCell")
|
||||
.field("value", &borrow)
|
||||
.finish()
|
||||
}
|
||||
Ok(borrow) => f.debug_struct("RefCell").field("value", &borrow).finish(),
|
||||
Err(_) => {
|
||||
// The RefCell is mutably borrowed so we can't look at its value
|
||||
// here. Show a placeholder instead.
|
||||
|
@ -2155,9 +2157,7 @@ impl<T: ?Sized + Debug> Debug for RefCell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
f.debug_struct("RefCell")
|
||||
.field("value", &BorrowedPlaceholder)
|
||||
.finish()
|
||||
f.debug_struct("RefCell").field("value", &BorrowedPlaceholder).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,8 @@ pub trait Hash {
|
|||
/// [`Hasher`]: trait.Hasher.html
|
||||
#[stable(feature = "hash_slice", since = "1.3.0")]
|
||||
fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
|
||||
where Self: Sized
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
for piece in data {
|
||||
piece.hash(state);
|
||||
|
@ -206,7 +207,9 @@ pub(crate) mod macros {
|
|||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro Hash($item:item) { /* compiler built-in */ }
|
||||
pub macro Hash($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
}
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[doc(inline)]
|
||||
|
@ -666,7 +669,6 @@ mod impls {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Hash> Hash for &T {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
|
@ -689,9 +691,7 @@ mod impls {
|
|||
state.write_usize(*self as *const () as usize);
|
||||
} else {
|
||||
// Fat pointer
|
||||
let (a, b) = unsafe {
|
||||
*(self as *const Self as *const (usize, usize))
|
||||
};
|
||||
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
|
||||
state.write_usize(a);
|
||||
state.write_usize(b);
|
||||
}
|
||||
|
@ -706,9 +706,7 @@ mod impls {
|
|||
state.write_usize(*self as *const () as usize);
|
||||
} else {
|
||||
// Fat pointer
|
||||
let (a, b) = unsafe {
|
||||
*(self as *const Self as *const (usize, usize))
|
||||
};
|
||||
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
|
||||
state.write_usize(a);
|
||||
state.write_usize(b);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
#![allow(deprecated)] // the types in this module are deprecated
|
||||
|
||||
use crate::marker::PhantomData;
|
||||
use crate::ptr;
|
||||
use crate::cmp;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
|
||||
/// An implementation of SipHash 1-3.
|
||||
///
|
||||
|
@ -16,8 +16,10 @@ use crate::mem;
|
|||
///
|
||||
/// See: <https://131002.net/siphash>
|
||||
#[unstable(feature = "hashmap_internals", issue = "0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[doc(hidden)]
|
||||
pub struct SipHasher13 {
|
||||
|
@ -28,8 +30,10 @@ pub struct SipHasher13 {
|
|||
///
|
||||
/// See: <https://131002.net/siphash/>
|
||||
#[unstable(feature = "hashmap_internals", issue = "0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct SipHasher24 {
|
||||
hasher: Hasher<Sip24Rounds>,
|
||||
|
@ -48,8 +52,10 @@ struct SipHasher24 {
|
|||
/// it is not intended for cryptographic purposes. As such, all
|
||||
/// cryptographic uses of this implementation are _strongly discouraged_.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SipHasher(SipHasher24);
|
||||
|
||||
|
@ -78,18 +84,23 @@ struct State {
|
|||
}
|
||||
|
||||
macro_rules! compress {
|
||||
($state:expr) => ({
|
||||
compress!($state.v0, $state.v1, $state.v2, $state.v3)
|
||||
});
|
||||
($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
|
||||
({
|
||||
$v0 = $v0.wrapping_add($v1); $v1 = $v1.rotate_left(13); $v1 ^= $v0;
|
||||
($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }};
|
||||
($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
|
||||
$v0 = $v0.wrapping_add($v1);
|
||||
$v1 = $v1.rotate_left(13);
|
||||
$v1 ^= $v0;
|
||||
$v0 = $v0.rotate_left(32);
|
||||
$v2 = $v2.wrapping_add($v3); $v3 = $v3.rotate_left(16); $v3 ^= $v2;
|
||||
$v0 = $v0.wrapping_add($v3); $v3 = $v3.rotate_left(21); $v3 ^= $v0;
|
||||
$v2 = $v2.wrapping_add($v1); $v1 = $v1.rotate_left(17); $v1 ^= $v2;
|
||||
$v2 = $v2.wrapping_add($v3);
|
||||
$v3 = $v3.rotate_left(16);
|
||||
$v3 ^= $v2;
|
||||
$v0 = $v0.wrapping_add($v3);
|
||||
$v3 = $v3.rotate_left(21);
|
||||
$v3 ^= $v0;
|
||||
$v2 = $v2.wrapping_add($v1);
|
||||
$v1 = $v1.rotate_left(17);
|
||||
$v1 ^= $v2;
|
||||
$v2 = $v2.rotate_left(32);
|
||||
});
|
||||
}};
|
||||
}
|
||||
|
||||
/// Loads an integer of the desired type from a byte stream, in LE order. Uses
|
||||
|
@ -98,15 +109,16 @@ macro_rules! compress {
|
|||
///
|
||||
/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
|
||||
macro_rules! load_int_le {
|
||||
($buf:expr, $i:expr, $int_ty:ident) =>
|
||||
({
|
||||
($buf:expr, $i:expr, $int_ty:ident) => {{
|
||||
debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
|
||||
let mut data = 0 as $int_ty;
|
||||
ptr::copy_nonoverlapping($buf.get_unchecked($i),
|
||||
ptr::copy_nonoverlapping(
|
||||
$buf.get_unchecked($i),
|
||||
&mut data as *mut _ as *mut u8,
|
||||
mem::size_of::<$int_ty>());
|
||||
mem::size_of::<$int_ty>(),
|
||||
);
|
||||
data.to_le()
|
||||
});
|
||||
}};
|
||||
}
|
||||
|
||||
/// Loads an u64 using up to 7 bytes of a byte slice.
|
||||
|
@ -137,8 +149,10 @@ impl SipHasher {
|
|||
/// Creates a new `SipHasher` with the two initial keys set to 0.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
pub fn new() -> SipHasher {
|
||||
SipHasher::new_with_keys(0, 0)
|
||||
}
|
||||
|
@ -146,12 +160,12 @@ impl SipHasher {
|
|||
/// Creates a `SipHasher` that is keyed off the provided keys.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
|
||||
SipHasher(SipHasher24 {
|
||||
hasher: Hasher::new_with_keys(key0, key1)
|
||||
})
|
||||
SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,8 +173,10 @@ impl SipHasher13 {
|
|||
/// Creates a new `SipHasher13` with the two initial keys set to 0.
|
||||
#[inline]
|
||||
#[unstable(feature = "hashmap_internals", issue = "0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
pub fn new() -> SipHasher13 {
|
||||
SipHasher13::new_with_keys(0, 0)
|
||||
}
|
||||
|
@ -168,12 +184,12 @@ impl SipHasher13 {
|
|||
/// Creates a `SipHasher13` that is keyed off the provided keys.
|
||||
#[inline]
|
||||
#[unstable(feature = "hashmap_internals", issue = "0")]
|
||||
#[rustc_deprecated(since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.13.0",
|
||||
reason = "use `std::collections::hash_map::DefaultHasher` instead"
|
||||
)]
|
||||
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
|
||||
SipHasher13 {
|
||||
hasher: Hasher::new_with_keys(key0, key1)
|
||||
}
|
||||
SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,12 +200,7 @@ impl<S: Sip> Hasher<S> {
|
|||
k0: key0,
|
||||
k1: key1,
|
||||
length: 0,
|
||||
state: State {
|
||||
v0: 0,
|
||||
v1: 0,
|
||||
v2: 0,
|
||||
v3: 0,
|
||||
},
|
||||
state: State { v0: 0, v1: 0, v2: 0, v3: 0 },
|
||||
tail: 0,
|
||||
ntail: 0,
|
||||
_marker: PhantomData,
|
||||
|
@ -294,7 +305,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {
|
|||
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail;
|
||||
if length < needed {
|
||||
self.ntail += length;
|
||||
return
|
||||
return;
|
||||
} else {
|
||||
self.state.v3 ^= self.tail;
|
||||
S::c_rounds(&mut self.state);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::fmt;
|
||||
use crate::ops::Try;
|
||||
|
||||
use super::super::{Iterator, DoubleEndedIterator, FusedIterator};
|
||||
use super::super::{DoubleEndedIterator, FusedIterator, Iterator};
|
||||
use super::Map;
|
||||
|
||||
/// An iterator that maps each element to an iterator, and yields the elements
|
||||
|
@ -15,7 +15,7 @@ use super::Map;
|
|||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct FlatMap<I, U: IntoIterator, F> {
|
||||
inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>
|
||||
inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
|
||||
}
|
||||
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
|
||||
pub(in super::super) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
|
||||
|
@ -28,7 +28,9 @@ impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
|
|||
where
|
||||
U: Clone + IntoIterator<IntoIter: Clone>,
|
||||
{
|
||||
fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
|
||||
fn clone(&self) -> Self {
|
||||
FlatMap { inner: self.inner.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
|
@ -43,26 +45,35 @@ where
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
|
||||
where F: FnMut(I::Item) -> U,
|
||||
where
|
||||
F: FnMut(I::Item) -> U,
|
||||
{
|
||||
type Item = U::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<U::Item> { self.inner.next() }
|
||||
fn next(&mut self) -> Option<U::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
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>
|
||||
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,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
self.inner.fold(init, fold)
|
||||
}
|
||||
|
@ -75,18 +86,24 @@ where
|
|||
U: IntoIterator<IntoIter: DoubleEndedIterator>,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
|
||||
fn next_back(&mut self) -> Option<U::Item> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
|
||||
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
|
||||
fn try_rfold<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_rfold(init, fold)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
|
||||
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
self.inner.rfold(init, fold)
|
||||
}
|
||||
|
@ -94,7 +111,12 @@ where
|
|||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
|
||||
where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
|
||||
where
|
||||
I: FusedIterator,
|
||||
U: IntoIterator,
|
||||
F: FnMut(I::Item) -> U,
|
||||
{
|
||||
}
|
||||
|
||||
/// An iterator that flattens one level of nesting in an iterator of things
|
||||
/// that can be turned into iterators.
|
||||
|
@ -133,7 +155,9 @@ where
|
|||
I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
|
||||
U: Clone + Iterator,
|
||||
{
|
||||
fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
|
||||
fn clone(&self) -> Self {
|
||||
Flatten { inner: self.inner.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_flatten", since = "1.29.0")]
|
||||
|
@ -145,21 +169,29 @@ where
|
|||
type Item = U::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<U::Item> { self.inner.next() }
|
||||
fn next(&mut self) -> Option<U::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
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>
|
||||
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,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
self.inner.fold(init, fold)
|
||||
}
|
||||
|
@ -172,18 +204,24 @@ where
|
|||
U: DoubleEndedIterator,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
|
||||
fn next_back(&mut self) -> Option<U::Item> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
|
||||
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
|
||||
fn try_rfold<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_rfold(init, fold)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
|
||||
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
self.inner.rfold(init, fold)
|
||||
}
|
||||
|
@ -194,7 +232,8 @@ impl<I, U> FusedIterator for Flatten<I>
|
|||
where
|
||||
I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
|
||||
U: Iterator,
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
|
||||
/// this type.
|
||||
|
@ -222,7 +261,9 @@ where
|
|||
fn next(&mut self) -> Option<U::Item> {
|
||||
loop {
|
||||
if let Some(ref mut inner) = self.frontiter {
|
||||
if let elt@Some(_) = inner.next() { return elt }
|
||||
if let elt @ Some(_) = inner.next() {
|
||||
return elt;
|
||||
}
|
||||
}
|
||||
match self.iter.next() {
|
||||
None => return self.backiter.as_mut()?.next(),
|
||||
|
@ -238,13 +279,16 @@ where
|
|||
let lo = flo.saturating_add(blo);
|
||||
match (self.iter.size_hint(), fhi, bhi) {
|
||||
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
|
||||
_ => (lo, None)
|
||||
_ => (lo, None),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
|
||||
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
|
||||
fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
|
||||
where
|
||||
Self: Sized,
|
||||
Fold: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Ok = Acc>,
|
||||
{
|
||||
#[inline]
|
||||
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
|
||||
|
@ -277,7 +321,8 @@ where
|
|||
|
||||
#[inline]
|
||||
fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
|
||||
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
#[inline]
|
||||
fn flatten<U: Iterator, Acc>(
|
||||
|
@ -286,7 +331,8 @@ where
|
|||
move |acc, iter| iter.fold(acc, &mut *fold)
|
||||
}
|
||||
|
||||
self.frontiter.into_iter()
|
||||
self.frontiter
|
||||
.into_iter()
|
||||
.chain(self.iter.map(IntoIterator::into_iter))
|
||||
.chain(self.backiter)
|
||||
.fold(init, flatten(fold))
|
||||
|
@ -302,7 +348,9 @@ where
|
|||
fn next_back(&mut self) -> Option<U::Item> {
|
||||
loop {
|
||||
if let Some(ref mut inner) = self.backiter {
|
||||
if let elt@Some(_) = inner.next_back() { return elt }
|
||||
if let elt @ Some(_) = inner.next_back() {
|
||||
return elt;
|
||||
}
|
||||
}
|
||||
match self.iter.next_back() {
|
||||
None => return self.frontiter.as_mut()?.next_back(),
|
||||
|
@ -312,14 +360,18 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
|
||||
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
|
||||
fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
|
||||
where
|
||||
Self: Sized,
|
||||
Fold: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Ok = Acc>,
|
||||
{
|
||||
#[inline]
|
||||
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
|
||||
backiter: &'a mut Option<T::IntoIter>,
|
||||
fold: &'a mut impl FnMut(Acc, T::Item) -> R,
|
||||
) -> impl FnMut(Acc, T) -> R + 'a where
|
||||
) -> impl FnMut(Acc, T) -> R + 'a
|
||||
where
|
||||
T::IntoIter: DoubleEndedIterator,
|
||||
{
|
||||
move |acc, x| {
|
||||
|
@ -348,7 +400,8 @@ where
|
|||
|
||||
#[inline]
|
||||
fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
|
||||
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> Acc,
|
||||
{
|
||||
#[inline]
|
||||
fn flatten<U: DoubleEndedIterator, Acc>(
|
||||
|
@ -357,7 +410,8 @@ where
|
|||
move |acc, iter| iter.rfold(acc, &mut *fold)
|
||||
}
|
||||
|
||||
self.frontiter.into_iter()
|
||||
self.frontiter
|
||||
.into_iter()
|
||||
.chain(self.iter.map(IntoIterator::into_iter))
|
||||
.chain(self.backiter)
|
||||
.rfold(init, flatten(fold))
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::{FusedIterator, TrustedLen};
|
|||
#[derive(Clone, Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Repeat<A> {
|
||||
element: A
|
||||
element: A,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -20,15 +20,21 @@ impl<A: Clone> Iterator for Repeat<A> {
|
|||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> { Some(self.element.clone()) }
|
||||
fn next(&mut self) -> Option<A> {
|
||||
Some(self.element.clone())
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(usize::MAX, None)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
Some(self.element.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
@ -104,7 +110,7 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
|
|||
#[derive(Copy, Clone, Debug)]
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
pub struct RepeatWith<F> {
|
||||
repeater: F
|
||||
repeater: F,
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
|
@ -112,10 +118,14 @@ impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
|
|||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> { Some((self.repeater)()) }
|
||||
fn next(&mut self) -> Option<A> {
|
||||
Some((self.repeater)())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(usize::MAX, None)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
|
@ -283,7 +293,7 @@ pub const fn empty<T>() -> Empty<T> {
|
|||
#[derive(Clone, Debug)]
|
||||
#[stable(feature = "iter_once", since = "1.2.0")]
|
||||
pub struct Once<T> {
|
||||
inner: crate::option::IntoIter<T>
|
||||
inner: crate::option::IntoIter<T>,
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_once", since = "1.2.0")]
|
||||
|
@ -530,7 +540,8 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
|
|||
#[inline]
|
||||
#[stable(feature = "iter_from_fn", since = "1.34.0")]
|
||||
pub fn from_fn<T, F>(f: F) -> FromFn<F>
|
||||
where F: FnMut() -> Option<T>
|
||||
where
|
||||
F: FnMut() -> Option<T>,
|
||||
{
|
||||
FromFn(f)
|
||||
}
|
||||
|
@ -547,7 +558,8 @@ pub struct FromFn<F>(F);
|
|||
|
||||
#[stable(feature = "iter_from_fn", since = "1.34.0")]
|
||||
impl<T, F> Iterator for FromFn<F>
|
||||
where F: FnMut() -> Option<T>
|
||||
where
|
||||
F: FnMut() -> Option<T>,
|
||||
{
|
||||
type Item = T;
|
||||
|
||||
|
@ -577,15 +589,13 @@ impl<F> fmt::Debug for FromFn<F> {
|
|||
/// ```
|
||||
#[stable(feature = "iter_successors", since = "1.34.0")]
|
||||
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
|
||||
where F: FnMut(&T) -> Option<T>
|
||||
where
|
||||
F: FnMut(&T) -> Option<T>,
|
||||
{
|
||||
// If this function returned `impl Iterator<Item=T>`
|
||||
// it could be based on `unfold` and not need a dedicated type.
|
||||
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
|
||||
Successors {
|
||||
next: first,
|
||||
succ,
|
||||
}
|
||||
Successors { next: first, succ }
|
||||
}
|
||||
|
||||
/// An new iterator where each successive item is computed based on the preceding one.
|
||||
|
@ -603,7 +613,8 @@ pub struct Successors<T, F> {
|
|||
|
||||
#[stable(feature = "iter_successors", since = "1.34.0")]
|
||||
impl<T, F> Iterator for Successors<T, F>
|
||||
where F: FnMut(&T) -> Option<T>
|
||||
where
|
||||
F: FnMut(&T) -> Option<T>,
|
||||
{
|
||||
type Item = T;
|
||||
|
||||
|
@ -616,24 +627,16 @@ impl<T, F> Iterator for Successors<T, F>
|
|||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
if self.next.is_some() {
|
||||
(1, None)
|
||||
} else {
|
||||
(0, Some(0))
|
||||
}
|
||||
if self.next.is_some() { (1, None) } else { (0, Some(0)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_successors", since = "1.34.0")]
|
||||
impl<T, F> FusedIterator for Successors<T, F>
|
||||
where F: FnMut(&T) -> Option<T>
|
||||
{}
|
||||
impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
|
||||
|
||||
#[stable(feature = "iter_successors", since = "1.34.0")]
|
||||
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Successors")
|
||||
.field("next", &self.next)
|
||||
.finish()
|
||||
f.debug_struct("Successors").field("next", &self.next).finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ops::{Mul, Add};
|
||||
use crate::num::Wrapping;
|
||||
use crate::iter;
|
||||
use crate::num::Wrapping;
|
||||
use crate::ops::{Add, Mul};
|
||||
|
||||
/// Trait to represent types that can be created by summing up an iterator.
|
||||
///
|
||||
|
@ -117,7 +117,8 @@ float_sum_product! { f32 f64 }
|
|||
|
||||
#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
|
||||
impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
|
||||
where T: Sum<U>,
|
||||
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,
|
||||
|
@ -137,7 +138,8 @@ impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
|
|||
/// assert_eq!(res, Ok(3));
|
||||
/// ```
|
||||
fn sum<I>(iter: I) -> Result<T, E>
|
||||
where I: Iterator<Item = Result<U, E>>,
|
||||
where
|
||||
I: Iterator<Item = Result<U, E>>,
|
||||
{
|
||||
iter::process_results(iter, |i| i.sum())
|
||||
}
|
||||
|
@ -145,13 +147,15 @@ impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
|
|||
|
||||
#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
|
||||
impl<T, U, E> Product<Result<U, E>> for Result<T, E>
|
||||
where T: Product<U>,
|
||||
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.
|
||||
fn product<I>(iter: I) -> Result<T, E>
|
||||
where I: Iterator<Item = Result<U, E>>,
|
||||
where
|
||||
I: Iterator<Item = Result<U, E>>,
|
||||
{
|
||||
iter::process_results(iter, |i| i.product())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ops::Try;
|
||||
use crate::iter::LoopState;
|
||||
use crate::ops::Try;
|
||||
|
||||
/// An iterator able to yield elements from both ends.
|
||||
///
|
||||
|
@ -113,7 +113,9 @@ pub trait DoubleEndedIterator: Iterator {
|
|||
#[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) }
|
||||
if n == 0 {
|
||||
return Some(x);
|
||||
}
|
||||
n -= 1;
|
||||
}
|
||||
None
|
||||
|
@ -157,7 +159,7 @@ pub trait DoubleEndedIterator: Iterator {
|
|||
where
|
||||
Self: Sized,
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Ok=B>
|
||||
R: Try<Ok = B>,
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next_back() {
|
||||
|
@ -279,7 +281,7 @@ pub trait DoubleEndedIterator: Iterator {
|
|||
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
#[inline]
|
||||
fn check<T>(
|
||||
|
|
|
@ -337,13 +337,17 @@ macro_rules! matches {
|
|||
#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
|
||||
#[doc(alias = "?")]
|
||||
macro_rules! r#try {
|
||||
($expr:expr) => (match $expr {
|
||||
($expr:expr) => {
|
||||
match $expr {
|
||||
$crate::result::Result::Ok(val) => val,
|
||||
$crate::result::Result::Err(err) => {
|
||||
return $crate::result::Result::Err($crate::convert::From::from(err))
|
||||
return $crate::result::Result::Err($crate::convert::From::from(err));
|
||||
}
|
||||
});
|
||||
($expr:expr,) => ($crate::r#try!($expr));
|
||||
}
|
||||
};
|
||||
($expr:expr,) => {
|
||||
$crate::r#try!($expr)
|
||||
};
|
||||
}
|
||||
|
||||
/// Writes formatted data into a buffer.
|
||||
|
@ -734,8 +738,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! compile_error {
|
||||
($msg:expr) => ({ /* compiler built-in */ });
|
||||
($msg:expr,) => ({ /* compiler built-in */ })
|
||||
($msg:expr) => {{ /* compiler built-in */ }};
|
||||
($msg:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Constructs parameters for the other string-formatting macros.
|
||||
|
@ -788,20 +792,23 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! format_args {
|
||||
($fmt:expr) => ({ /* compiler built-in */ });
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
($fmt:expr) => {{ /* compiler built-in */ }};
|
||||
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Same as `format_args`, but adds a newline in the end.
|
||||
#[unstable(feature = "format_args_nl", issue = "0",
|
||||
#[unstable(
|
||||
feature = "format_args_nl",
|
||||
issue = "0",
|
||||
reason = "`format_args_nl` is only for internal \
|
||||
language use and is subject to change")]
|
||||
language use and is subject to change"
|
||||
)]
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! format_args_nl {
|
||||
($fmt:expr) => ({ /* compiler built-in */ });
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
($fmt:expr) => {{ /* compiler built-in */ }};
|
||||
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Inspects an environment variable at compile time.
|
||||
|
@ -839,8 +846,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! env {
|
||||
($name:expr) => ({ /* compiler built-in */ });
|
||||
($name:expr,) => ({ /* compiler built-in */ })
|
||||
($name:expr) => {{ /* compiler built-in */ }};
|
||||
($name:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Optionally inspects an environment variable at compile time.
|
||||
|
@ -866,8 +873,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! option_env {
|
||||
($name:expr) => ({ /* compiler built-in */ });
|
||||
($name:expr,) => ({ /* compiler built-in */ })
|
||||
($name:expr) => {{ /* compiler built-in */ }};
|
||||
($name:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Concatenates identifiers into one identifier.
|
||||
|
@ -894,13 +901,16 @@ pub(crate) mod builtin {
|
|||
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
|
||||
/// # }
|
||||
/// ```
|
||||
#[unstable(feature = "concat_idents", issue = "29599",
|
||||
reason = "`concat_idents` is not stable enough for use and is subject to change")]
|
||||
#[unstable(
|
||||
feature = "concat_idents",
|
||||
issue = "29599",
|
||||
reason = "`concat_idents` is not stable enough for use and is subject to change"
|
||||
)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! concat_idents {
|
||||
($($e:ident),+) => ({ /* compiler built-in */ });
|
||||
($($e:ident,)+) => ({ /* compiler built-in */ })
|
||||
($($e:ident),+) => {{ /* compiler built-in */ }};
|
||||
($($e:ident,)+) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Concatenates literals into a static string slice.
|
||||
|
@ -922,8 +932,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! concat {
|
||||
($($e:expr),*) => ({ /* compiler built-in */ });
|
||||
($($e:expr,)*) => ({ /* compiler built-in */ })
|
||||
($($e:expr),*) => {{ /* compiler built-in */ }};
|
||||
($($e:expr,)*) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Expands to the line number on which it was invoked.
|
||||
|
@ -950,7 +960,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! line { () => { /* compiler built-in */ } }
|
||||
macro_rules! line {
|
||||
() => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Expands to the column number at which it was invoked.
|
||||
///
|
||||
|
@ -976,7 +990,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! column { () => { /* compiler built-in */ } }
|
||||
macro_rules! column {
|
||||
() => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Expands to the file name in which it was invoked.
|
||||
///
|
||||
|
@ -1001,7 +1019,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! file { () => { /* compiler built-in */ } }
|
||||
macro_rules! file {
|
||||
() => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Stringifies its arguments.
|
||||
///
|
||||
|
@ -1021,7 +1043,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
|
||||
macro_rules! stringify {
|
||||
($($t:tt)*) => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Includes a utf8-encoded file as a string.
|
||||
///
|
||||
|
@ -1057,8 +1083,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! include_str {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
($file:expr) => {{ /* compiler built-in */ }};
|
||||
($file:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Includes a file as a reference to a byte array.
|
||||
|
@ -1095,8 +1121,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! include_bytes {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
($file:expr) => {{ /* compiler built-in */ }};
|
||||
($file:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Expands to a string that represents the current module path.
|
||||
|
@ -1119,7 +1145,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! module_path { () => { /* compiler built-in */ } }
|
||||
macro_rules! module_path {
|
||||
() => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Evaluates boolean combinations of configuration flags at compile-time.
|
||||
///
|
||||
|
@ -1144,7 +1174,11 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
|
||||
macro_rules! cfg {
|
||||
($($cfg:tt)*) => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Parses a file as an expression or an item according to the context.
|
||||
///
|
||||
|
@ -1189,8 +1223,8 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! include {
|
||||
($file:expr) => ({ /* compiler built-in */ });
|
||||
($file:expr,) => ({ /* compiler built-in */ })
|
||||
($file:expr) => {{ /* compiler built-in */ }};
|
||||
($file:expr,) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Asserts that a boolean expression is `true` at runtime.
|
||||
|
@ -1242,9 +1276,9 @@ pub(crate) mod builtin {
|
|||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! assert {
|
||||
($cond:expr) => ({ /* compiler built-in */ });
|
||||
($cond:expr,) => ({ /* compiler built-in */ });
|
||||
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
|
||||
($cond:expr) => {{ /* compiler built-in */ }};
|
||||
($cond:expr,) => {{ /* compiler built-in */ }};
|
||||
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Inline assembly.
|
||||
|
@ -1252,75 +1286,118 @@ pub(crate) mod builtin {
|
|||
/// Read the [unstable book] for the usage.
|
||||
///
|
||||
/// [unstable book]: ../unstable-book/library-features/asm.html
|
||||
#[unstable(feature = "asm", issue = "29722",
|
||||
reason = "inline assembly is not stable enough for use and is subject to change")]
|
||||
#[unstable(
|
||||
feature = "asm",
|
||||
issue = "29722",
|
||||
reason = "inline assembly is not stable enough for use and is subject to change"
|
||||
)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! asm { ("assembly template"
|
||||
macro_rules! asm {
|
||||
("assembly template"
|
||||
: $("output"(operand),)*
|
||||
: $("input"(operand),)*
|
||||
: $("clobbers",)*
|
||||
: $("options",)*) => { /* compiler built-in */ } }
|
||||
: $("options",)*) => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Module-level inline assembly.
|
||||
#[unstable(feature = "global_asm", issue = "35119",
|
||||
reason = "`global_asm!` is not stable enough for use and is subject to change")]
|
||||
#[unstable(
|
||||
feature = "global_asm",
|
||||
issue = "35119",
|
||||
reason = "`global_asm!` is not stable enough for use and is subject to change"
|
||||
)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! global_asm { ("assembly") => { /* compiler built-in */ } }
|
||||
macro_rules! global_asm {
|
||||
("assembly") => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Prints passed tokens into the standard output.
|
||||
#[unstable(feature = "log_syntax", issue = "29598",
|
||||
reason = "`log_syntax!` is not stable enough for use and is subject to change")]
|
||||
#[unstable(
|
||||
feature = "log_syntax",
|
||||
issue = "29598",
|
||||
reason = "`log_syntax!` is not stable enough for use and is subject to change"
|
||||
)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! log_syntax { ($($arg:tt)*) => { /* compiler built-in */ } }
|
||||
macro_rules! log_syntax {
|
||||
($($arg:tt)*) => {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// Enables or disables tracing functionality used for debugging other macros.
|
||||
#[unstable(feature = "trace_macros", issue = "29598",
|
||||
reason = "`trace_macros` is not stable enough for use and is subject to change")]
|
||||
#[unstable(
|
||||
feature = "trace_macros",
|
||||
issue = "29598",
|
||||
reason = "`trace_macros` is not stable enough for use and is subject to change"
|
||||
)]
|
||||
#[rustc_builtin_macro]
|
||||
#[macro_export]
|
||||
macro_rules! trace_macros {
|
||||
(true) => ({ /* compiler built-in */ });
|
||||
(false) => ({ /* compiler built-in */ })
|
||||
(true) => {{ /* compiler built-in */ }};
|
||||
(false) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a unit test.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro test($item:item) { /* compiler built-in */ }
|
||||
pub macro test($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a benchmark test.
|
||||
#[unstable(soft, feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable")]
|
||||
#[unstable(
|
||||
feature = "test",
|
||||
issue = "50297",
|
||||
soft,
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable"
|
||||
)]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro bench($item:item) { /* compiler built-in */ }
|
||||
pub macro bench($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// An implementation detail of the `#[test]` and `#[bench]` macros.
|
||||
#[unstable(feature = "custom_test_frameworks", issue = "50297",
|
||||
reason = "custom test frameworks are an unstable feature")]
|
||||
#[unstable(
|
||||
feature = "custom_test_frameworks",
|
||||
issue = "50297",
|
||||
reason = "custom test frameworks are an unstable feature"
|
||||
)]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro test_case($item:item) { /* compiler built-in */ }
|
||||
pub macro test_case($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// Attribute macro applied to a static to register it as a global allocator.
|
||||
#[stable(feature = "global_allocator", since = "1.28.0")]
|
||||
#[allow_internal_unstable(rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro global_allocator($item:item) { /* compiler built-in */ }
|
||||
pub macro global_allocator($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
|
||||
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
|
||||
pub macro RustcDecodable($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// Unstable implementation detail of the `rustc` compiler, do not use.
|
||||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(core_intrinsics)]
|
||||
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
|
||||
pub macro RustcEncodable($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ptr;
|
||||
use crate::ops::{Deref, DerefMut};
|
||||
use crate::ptr;
|
||||
|
||||
/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
|
||||
///
|
||||
|
|
|
@ -12,13 +12,15 @@
|
|||
// This module is only for dec2flt and flt2dec, and only public because of coretests.
|
||||
// It is not intended to ever be stabilized.
|
||||
#![doc(hidden)]
|
||||
#![unstable(feature = "core_private_bignum",
|
||||
#![unstable(
|
||||
feature = "core_private_bignum",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
#![macro_use]
|
||||
|
||||
use crate::mem;
|
||||
use crate::intrinsics;
|
||||
use crate::mem;
|
||||
|
||||
/// Arithmetic operations required by bignums.
|
||||
pub trait FullOps: Sized {
|
||||
|
@ -36,9 +38,7 @@ pub trait FullOps: Sized {
|
|||
|
||||
/// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem`
|
||||
/// and `0 <= rem < other`, where `W` is the number of bits in `Self`.
|
||||
fn full_div_rem(self,
|
||||
other: Self,
|
||||
borrow: Self)
|
||||
fn full_div_rem(self, other: Self, borrow: Self)
|
||||
-> (Self /* quotient */, Self /* remainder */);
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ impl_full_ops! {
|
|||
const SMALL_POW5: [(u64, usize); 3] = [(125, 3), (15625, 6), (1_220_703_125, 13)];
|
||||
|
||||
macro_rules! define_bignum {
|
||||
($name:ident: type=$ty:ty, n=$n:expr) => (
|
||||
($name:ident: type=$ty:ty, n=$n:expr) => {
|
||||
/// Stack-allocated arbitrary-precision (up to certain limit) integer.
|
||||
///
|
||||
/// This is backed by a fixed-size array of given type ("digit").
|
||||
|
@ -115,7 +115,7 @@ macro_rules! define_bignum {
|
|||
size: usize,
|
||||
/// Digits. `[a, b, c, ...]` represents `a + b*2^W + c*2^(2W) + ...`
|
||||
/// where `W` is the number of bits in the digit type.
|
||||
base: [$ty; $n]
|
||||
base: [$ty; $n],
|
||||
}
|
||||
|
||||
impl $name {
|
||||
|
@ -293,8 +293,8 @@ macro_rules! define_bignum {
|
|||
sz += 1;
|
||||
}
|
||||
for i in (digits + 1..last).rev() {
|
||||
self.base[i] = (self.base[i] << bits) |
|
||||
(self.base[i-1] >> (digitbits - bits));
|
||||
self.base[i] =
|
||||
(self.base[i] << bits) | (self.base[i - 1] >> (digitbits - bits));
|
||||
}
|
||||
self.base[digits] <<= bits;
|
||||
// self.base[..digits] is zero, no need to shift
|
||||
|
@ -331,7 +331,6 @@ macro_rules! define_bignum {
|
|||
self
|
||||
}
|
||||
|
||||
|
||||
/// Multiplies itself by a number described by `other[0] + other[1] * 2^W +
|
||||
/// other[2] * 2^(2W) + ...` (where `W` is the number of bits in the digit type)
|
||||
/// and returns its own mutable reference.
|
||||
|
@ -342,7 +341,9 @@ macro_rules! define_bignum {
|
|||
|
||||
let mut retsz = 0;
|
||||
for (i, &a) in aa.iter().enumerate() {
|
||||
if a == 0 { continue; }
|
||||
if a == 0 {
|
||||
continue;
|
||||
}
|
||||
let mut sz = bb.len();
|
||||
let mut carry = 0;
|
||||
for (j, &b) in bb.iter().enumerate() {
|
||||
|
@ -430,11 +431,12 @@ macro_rules! define_bignum {
|
|||
}
|
||||
|
||||
impl crate::cmp::PartialEq for $name {
|
||||
fn eq(&self, other: &$name) -> bool { self.base[..] == other.base[..] }
|
||||
fn eq(&self, other: &$name) -> bool {
|
||||
self.base[..] == other.base[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::cmp::Eq for $name {
|
||||
}
|
||||
impl crate::cmp::Eq for $name {}
|
||||
|
||||
impl crate::cmp::PartialOrd for $name {
|
||||
fn partial_cmp(&self, other: &$name) -> crate::option::Option<crate::cmp::Ordering> {
|
||||
|
@ -472,7 +474,7 @@ macro_rules! define_bignum {
|
|||
crate::result::Result::Ok(())
|
||||
}
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// The digit type for `Big32x40`.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//! The various algorithms from the paper.
|
||||
|
||||
use crate::cmp::min;
|
||||
use crate::cmp::Ordering::{Less, Equal, Greater};
|
||||
use crate::num::diy_float::Fp;
|
||||
use crate::num::dec2flt::table;
|
||||
use crate::num::dec2flt::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float};
|
||||
use crate::cmp::Ordering::{Equal, Greater, Less};
|
||||
use crate::num::dec2flt::num::{self, Big};
|
||||
use crate::num::dec2flt::rawfp::{self, fp_to_float, next_float, prev_float, RawFloat, Unpacked};
|
||||
use crate::num::dec2flt::table;
|
||||
use crate::num::diy_float::Fp;
|
||||
|
||||
/// Number of significand bits in Fp
|
||||
const P: u32 = 64;
|
||||
|
|
|
@ -78,23 +78,25 @@
|
|||
//! turned into {positive,negative} {zero,infinity}.
|
||||
|
||||
#![doc(hidden)]
|
||||
#![unstable(feature = "dec2flt",
|
||||
#![unstable(
|
||||
feature = "dec2flt",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
|
||||
use crate::fmt;
|
||||
use crate::str::FromStr;
|
||||
|
||||
use self::parse::{parse_decimal, Decimal, Sign, ParseResult};
|
||||
use self::num::digits_to_big;
|
||||
use self::parse::{parse_decimal, Decimal, ParseResult, Sign};
|
||||
use self::rawfp::RawFloat;
|
||||
|
||||
mod algorithm;
|
||||
mod table;
|
||||
mod num;
|
||||
mod table;
|
||||
// These two have their own tests.
|
||||
pub mod rawfp;
|
||||
pub mod parse;
|
||||
pub mod rawfp;
|
||||
|
||||
macro_rules! from_str_float_impl {
|
||||
($t:ty) => {
|
||||
|
@ -155,7 +157,7 @@ macro_rules! from_str_float_impl {
|
|||
dec2flt(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
from_str_float_impl!(f32);
|
||||
from_str_float_impl!(f64);
|
||||
|
@ -171,7 +173,7 @@ from_str_float_impl!(f64);
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ParseFloatError {
|
||||
kind: FloatErrorKind
|
||||
kind: FloatErrorKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -181,10 +183,12 @@ enum FloatErrorKind {
|
|||
}
|
||||
|
||||
impl ParseFloatError {
|
||||
#[unstable(feature = "int_error_internals",
|
||||
#[unstable(
|
||||
feature = "int_error_internals",
|
||||
reason = "available through Error trait and this method should \
|
||||
not be exposed publicly",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn __description(&self) -> &str {
|
||||
match self.kind {
|
||||
|
@ -222,7 +226,7 @@ fn extract_sign(s: &str) -> (Sign, &str) {
|
|||
/// Converts a decimal string into a floating point number.
|
||||
fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
|
||||
if s.is_empty() {
|
||||
return Err(pfe_empty())
|
||||
return Err(pfe_empty());
|
||||
}
|
||||
let (sign, s) = extract_sign(s);
|
||||
let flt = match parse_decimal(s) {
|
||||
|
@ -232,8 +236,10 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
|
|||
ParseResult::Invalid => match s {
|
||||
"inf" => T::INFINITY,
|
||||
"NaN" => T::NAN,
|
||||
_ => { return Err(pfe_invalid()); }
|
||||
_ => {
|
||||
return Err(pfe_invalid());
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
match sign {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// FIXME This module's name is a bit unfortunate, since other modules also import `core::num`.
|
||||
|
||||
use crate::cmp::Ordering::{self, Less, Equal, Greater};
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
|
||||
pub use crate::num::bignum::Big32x40 as Big;
|
||||
|
||||
|
@ -36,7 +36,10 @@ pub fn compare_with_half_ulp(f: &Big, ones_place: usize) -> Ordering {
|
|||
/// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and
|
||||
/// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is
|
||||
/// more complicated than this entire function.
|
||||
pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 where T : IntoIterator<Item=&'a u8> {
|
||||
pub fn from_str_unchecked<'a, T>(bytes: T) -> u64
|
||||
where
|
||||
T: IntoIterator<Item = &'a u8>,
|
||||
{
|
||||
let mut result = 0;
|
||||
for &c in bytes {
|
||||
result = result * 10 + (c - b'0') as u64;
|
||||
|
@ -61,13 +64,8 @@ pub fn digits_to_big(integral: &[u8], fractional: &[u8]) -> Big {
|
|||
pub fn to_u64(x: &Big) -> u64 {
|
||||
assert!(x.bit_length() < 64);
|
||||
let d = x.digits();
|
||||
if d.len() < 2 {
|
||||
d[0] as u64
|
||||
} else {
|
||||
(d[1] as u64) << 32 | d[0] as u64
|
||||
if d.len() < 2 { d[0] as u64 } else { (d[1] as u64) << 32 | d[0] as u64 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Extracts a range of bits.
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
//! modules rely on to not panic (or overflow) in turn.
|
||||
//! To make matters worse, all that happens in a single pass over the input.
|
||||
//! So, be careful when modifying anything, and double-check with the other modules.
|
||||
use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid};
|
||||
use super::num;
|
||||
use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Sign {
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
|
||||
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
|
||||
//! That algorithm needs only next_float() which does handle subnormals and zeros.
|
||||
use crate::cmp::Ordering::{Less, Equal, Greater};
|
||||
use crate::cmp::Ordering::{Equal, Greater, Less};
|
||||
use crate::convert::{TryFrom, TryInto};
|
||||
use crate::ops::{Add, Mul, Div, Neg};
|
||||
use crate::fmt::{Debug, LowerExp};
|
||||
use crate::num::diy_float::Fp;
|
||||
use crate::num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
|
||||
use crate::num::FpCategory;
|
||||
use crate::num::dec2flt::num::{self, Big};
|
||||
use crate::num::dec2flt::table;
|
||||
use crate::num::diy_float::Fp;
|
||||
use crate::num::FpCategory;
|
||||
use crate::num::FpCategory::{Infinite, Nan, Normal, Subnormal, Zero};
|
||||
use crate::ops::{Add, Div, Mul, Neg};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Unpacked {
|
||||
|
@ -44,13 +44,8 @@ impl Unpacked {
|
|||
/// See the parent module's doc comment for why this is necessary.
|
||||
///
|
||||
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
|
||||
pub trait RawFloat
|
||||
: Copy
|
||||
+ Debug
|
||||
+ LowerExp
|
||||
+ Mul<Output=Self>
|
||||
+ Div<Output=Self>
|
||||
+ Neg<Output=Self>
|
||||
pub trait RawFloat:
|
||||
Copy + Debug + LowerExp + Mul<Output = Self> + Div<Output = Self> + Neg<Output = Self>
|
||||
{
|
||||
const INFINITY: Self;
|
||||
const NAN: Self;
|
||||
|
@ -144,7 +139,7 @@ macro_rules! other_constants {
|
|||
const INFINITY: Self = $crate::$type::INFINITY;
|
||||
const NAN: Self = $crate::$type::NAN;
|
||||
const ZERO: Self = 0.0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl RawFloat for f32 {
|
||||
|
@ -163,11 +158,8 @@ impl RawFloat for f32 {
|
|||
let bits = self.to_bits();
|
||||
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
|
||||
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
|
||||
let mantissa = if exponent == 0 {
|
||||
(bits & 0x7fffff) << 1
|
||||
} else {
|
||||
(bits & 0x7fffff) | 0x800000
|
||||
};
|
||||
let mantissa =
|
||||
if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
|
||||
// Exponent bias + mantissa shift
|
||||
exponent -= 127 + 23;
|
||||
(mantissa as u64, exponent, sign)
|
||||
|
@ -188,11 +180,16 @@ impl RawFloat for f32 {
|
|||
table::F32_SHORT_POWERS[e]
|
||||
}
|
||||
|
||||
fn classify(self) -> FpCategory { self.classify() }
|
||||
fn to_bits(self) -> Self::Bits { self.to_bits() }
|
||||
fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
|
||||
fn classify(self) -> FpCategory {
|
||||
self.classify()
|
||||
}
|
||||
fn to_bits(self) -> Self::Bits {
|
||||
self.to_bits()
|
||||
}
|
||||
fn from_bits(v: Self::Bits) -> Self {
|
||||
Self::from_bits(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl RawFloat for f64 {
|
||||
type Bits = u64;
|
||||
|
@ -235,9 +232,15 @@ impl RawFloat for f64 {
|
|||
table::F64_SHORT_POWERS[e]
|
||||
}
|
||||
|
||||
fn classify(self) -> FpCategory { self.classify() }
|
||||
fn to_bits(self) -> Self::Bits { self.to_bits() }
|
||||
fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
|
||||
fn classify(self) -> FpCategory {
|
||||
self.classify()
|
||||
}
|
||||
fn to_bits(self) -> Self::Bits {
|
||||
self.to_bits()
|
||||
}
|
||||
fn from_bits(v: Self::Bits) -> Self {
|
||||
Self::from_bits(v)
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts an `Fp` to the closest machine float type.
|
||||
|
@ -278,14 +281,15 @@ pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
|
|||
/// Inverse of `RawFloat::unpack()` for normalized numbers.
|
||||
/// Panics if the significand or exponent are not valid for normalized numbers.
|
||||
pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
|
||||
debug_assert!(T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG,
|
||||
"encode_normal: significand not normalized");
|
||||
debug_assert!(
|
||||
T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG,
|
||||
"encode_normal: significand not normalized"
|
||||
);
|
||||
// Remove the hidden bit
|
||||
let sig_enc = x.sig & !(1 << T::EXPLICIT_SIG_BITS);
|
||||
// Adjust the exponent for exponent bias and mantissa shift
|
||||
let k_enc = x.k + T::MAX_EXP + T::EXPLICIT_SIG_BITS as i16;
|
||||
debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP,
|
||||
"encode_normal: exponent out of range");
|
||||
debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP, "encode_normal: exponent out of range");
|
||||
// Leave sign bit at 0 ("+"), our numbers are all positive
|
||||
let bits = (k_enc as u64) << T::EXPLICIT_SIG_BITS | sig_enc;
|
||||
T::from_bits(bits.try_into().unwrap_or_else(|_| unreachable!()))
|
||||
|
@ -315,7 +319,7 @@ pub fn big_to_fp(f: &Big) -> Fp {
|
|||
Equal | Greater => match leading.checked_add(1) {
|
||||
Some(f) => Fp { f, e }.normalize(),
|
||||
None => Fp { f: 1 << 63, e: e + 1 },
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,8 +358,6 @@ pub fn next_float<T: RawFloat>(x: T) -> T {
|
|||
// want, and the mantissa bits become zero. Because of the hidden bit convention, this
|
||||
// too is exactly what we want!
|
||||
// Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
|
||||
Zero | Subnormal | Normal => {
|
||||
T::from_bits(x.to_bits() + T::Bits::from(1u8))
|
||||
}
|
||||
Zero | Subnormal | Normal => T::from_bits(x.to_bits() + T::Bits::from(1u8)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
// This module is only for dec2flt and flt2dec, and only public because of coretests.
|
||||
// It is not intended to ever be stabilized.
|
||||
#![doc(hidden)]
|
||||
#![unstable(feature = "core_private_diy_float",
|
||||
#![unstable(
|
||||
feature = "core_private_diy_float",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
|
||||
/// A custom 64-bit floating point type, representing `f * 2^e`.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -74,9 +76,6 @@ impl Fp {
|
|||
assert!(edelta >= 0);
|
||||
let edelta = edelta as usize;
|
||||
assert_eq!(self.f << edelta >> edelta, self.f);
|
||||
Fp {
|
||||
f: self.f << edelta,
|
||||
e,
|
||||
}
|
||||
Fp { f: self.f << edelta, e }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Decodes a floating-point value into individual parts and error ranges.
|
||||
|
||||
use crate::{f32, f64};
|
||||
use crate::num::FpCategory;
|
||||
use crate::num::dec2flt::rawfp::RawFloat;
|
||||
use crate::num::FpCategory;
|
||||
use crate::{f32, f64};
|
||||
|
||||
/// Decoded unsigned finite value, such that:
|
||||
///
|
||||
|
@ -47,11 +47,15 @@ pub trait DecodableFloat: RawFloat + Copy {
|
|||
}
|
||||
|
||||
impl DecodableFloat for f32 {
|
||||
fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE }
|
||||
fn min_pos_norm_value() -> Self {
|
||||
f32::MIN_POSITIVE
|
||||
}
|
||||
}
|
||||
|
||||
impl DecodableFloat for f64 {
|
||||
fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE }
|
||||
fn min_pos_norm_value() -> Self {
|
||||
f64::MIN_POSITIVE
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a sign (true when negative) and `FullDecoded` value
|
||||
|
@ -67,20 +71,29 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
|
|||
// neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp)
|
||||
// Float::integer_decode always preserves the exponent,
|
||||
// so the mantissa is scaled for subnormals.
|
||||
FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1,
|
||||
exp, inclusive: even })
|
||||
FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1, exp, inclusive: even })
|
||||
}
|
||||
FpCategory::Normal => {
|
||||
let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode();
|
||||
if mant == minnorm.0 {
|
||||
// neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
|
||||
// where maxmant = minnormmant * 2 - 1
|
||||
FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2,
|
||||
exp: exp - 2, inclusive: even })
|
||||
FullDecoded::Finite(Decoded {
|
||||
mant: mant << 2,
|
||||
minus: 1,
|
||||
plus: 2,
|
||||
exp: exp - 2,
|
||||
inclusive: even,
|
||||
})
|
||||
} else {
|
||||
// neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp)
|
||||
FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1,
|
||||
exp: exp - 1, inclusive: even })
|
||||
FullDecoded::Finite(Decoded {
|
||||
mant: mant << 1,
|
||||
minus: 1,
|
||||
plus: 1,
|
||||
exp: exp - 1,
|
||||
inclusive: even,
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -116,15 +116,17 @@ functions.
|
|||
// while this is extensively documented, this is in principle private which is
|
||||
// only made public for testing. do not expose us.
|
||||
#![doc(hidden)]
|
||||
#![unstable(feature = "flt2dec",
|
||||
#![unstable(
|
||||
feature = "flt2dec",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "0")]
|
||||
issue = "0"
|
||||
)]
|
||||
|
||||
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
|
||||
use crate::i16;
|
||||
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
|
||||
|
||||
pub mod estimator;
|
||||
pub mod decoder;
|
||||
pub mod estimator;
|
||||
|
||||
/// Digit-generation algorithms.
|
||||
pub mod strategy {
|
||||
|
@ -144,17 +146,24 @@ pub const MAX_SIG_DIGITS: usize = 17;
|
|||
#[doc(hidden)]
|
||||
pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> {
|
||||
match d[..n].iter().rposition(|&c| c != b'9') {
|
||||
Some(i) => { // d[i+1..n] is all nines
|
||||
Some(i) => {
|
||||
// d[i+1..n] is all nines
|
||||
d[i] += 1;
|
||||
for j in i+1..n { d[j] = b'0'; }
|
||||
for j in i + 1..n {
|
||||
d[j] = b'0';
|
||||
}
|
||||
None
|
||||
}
|
||||
None if n > 0 => { // 999..999 rounds to 1000..000 with an increased exponent
|
||||
None if n > 0 => {
|
||||
// 999..999 rounds to 1000..000 with an increased exponent
|
||||
d[0] = b'1';
|
||||
for j in 1..n { d[j] = b'0'; }
|
||||
for j in 1..n {
|
||||
d[j] = b'0';
|
||||
}
|
||||
Some(b'0')
|
||||
}
|
||||
None => { // an empty buffer rounds up (a bit strange but reasonable)
|
||||
None => {
|
||||
// an empty buffer rounds up (a bit strange but reasonable)
|
||||
Some(b'1')
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +185,19 @@ impl<'a> Part<'a> {
|
|||
pub fn len(&self) -> usize {
|
||||
match *self {
|
||||
Part::Zero(nzeroes) => nzeroes,
|
||||
Part::Num(v) => if v < 1_000 { if v < 10 { 1 } else if v < 100 { 2 } else { 3 } }
|
||||
else { if v < 10_000 { 4 } else { 5 } },
|
||||
Part::Num(v) => {
|
||||
if v < 1_000 {
|
||||
if v < 10 {
|
||||
1
|
||||
} else if v < 100 {
|
||||
2
|
||||
} else {
|
||||
3
|
||||
}
|
||||
} else {
|
||||
if v < 10_000 { 4 } else { 5 }
|
||||
}
|
||||
}
|
||||
Part::Copy(buf) => buf.len(),
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +210,9 @@ impl<'a> Part<'a> {
|
|||
if out.len() >= len {
|
||||
match *self {
|
||||
Part::Zero(nzeroes) => {
|
||||
for c in &mut out[..nzeroes] { *c = b'0'; }
|
||||
for c in &mut out[..nzeroes] {
|
||||
*c = b'0';
|
||||
}
|
||||
}
|
||||
Part::Num(mut v) => {
|
||||
for c in out[..len].iter_mut().rev() {
|
||||
|
@ -234,7 +256,9 @@ impl<'a> Formatted<'a> {
|
|||
/// Returns the number of written bytes, or `None` if the buffer is not enough.
|
||||
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
|
||||
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
|
||||
if out.len() < self.sign.len() { return None; }
|
||||
if out.len() < self.sign.len() {
|
||||
return None;
|
||||
}
|
||||
out[..self.sign.len()].copy_from_slice(self.sign);
|
||||
|
||||
let mut written = self.sign.len();
|
||||
|
@ -254,8 +278,12 @@ impl<'a> Formatted<'a> {
|
|||
/// it will be ignored and full digits will be printed. It is only used to print
|
||||
/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that
|
||||
/// it will only print given digits and nothing else.
|
||||
fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize,
|
||||
parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
|
||||
fn digits_to_dec_str<'a>(
|
||||
buf: &'a [u8],
|
||||
exp: i16,
|
||||
frac_digits: usize,
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> &'a [Part<'a>] {
|
||||
assert!(!buf.is_empty());
|
||||
assert!(buf[0] > b'0');
|
||||
assert!(parts.len() >= 4);
|
||||
|
@ -322,8 +350,13 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize,
|
|||
/// it will be ignored and full digits will be printed. It is only used to print
|
||||
/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
|
||||
/// it will only print the given digits and nothing else.
|
||||
fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool,
|
||||
parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
|
||||
fn digits_to_exp_str<'a>(
|
||||
buf: &'a [u8],
|
||||
exp: i16,
|
||||
min_ndigits: usize,
|
||||
upper: bool,
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> &'a [Part<'a>] {
|
||||
assert!(!buf.is_empty());
|
||||
assert!(buf[0] > b'0');
|
||||
assert!(parts.len() >= 6);
|
||||
|
@ -374,11 +407,35 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
|
|||
match (*decoded, sign) {
|
||||
(FullDecoded::Nan, _) => b"",
|
||||
(FullDecoded::Zero, Sign::Minus) => b"",
|
||||
(FullDecoded::Zero, Sign::MinusRaw) => if negative { b"-" } else { b"" },
|
||||
(FullDecoded::Zero, Sign::MinusRaw) => {
|
||||
if negative {
|
||||
b"-"
|
||||
} else {
|
||||
b""
|
||||
}
|
||||
}
|
||||
(FullDecoded::Zero, Sign::MinusPlus) => b"+",
|
||||
(FullDecoded::Zero, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" },
|
||||
(_, Sign::Minus) | (_, Sign::MinusRaw) => if negative { b"-" } else { b"" },
|
||||
(_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" },
|
||||
(FullDecoded::Zero, Sign::MinusPlusRaw) => {
|
||||
if negative {
|
||||
b"-"
|
||||
} else {
|
||||
b"+"
|
||||
}
|
||||
}
|
||||
(_, Sign::Minus) | (_, Sign::MinusRaw) => {
|
||||
if negative {
|
||||
b"-"
|
||||
} else {
|
||||
b""
|
||||
}
|
||||
}
|
||||
(_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => {
|
||||
if negative {
|
||||
b"-"
|
||||
} else {
|
||||
b"+"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,10 +457,19 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
|
|||
/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
|
||||
/// There should be at least 4 parts available, due to the worst case like
|
||||
/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
|
||||
pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
|
||||
sign: Sign, frac_digits: usize, _upper: bool,
|
||||
buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
|
||||
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
|
||||
pub fn to_shortest_str<'a, T, F>(
|
||||
mut format_shortest: F,
|
||||
v: T,
|
||||
sign: Sign,
|
||||
frac_digits: usize,
|
||||
_upper: bool,
|
||||
buf: &'a mut [u8],
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> Formatted<'a>
|
||||
where
|
||||
T: DecodableFloat,
|
||||
F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
|
||||
{
|
||||
assert!(parts.len() >= 4);
|
||||
assert!(buf.len() >= MAX_SIG_DIGITS);
|
||||
|
||||
|
@ -419,7 +485,8 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
|
|||
Formatted { sign, parts: &parts[..1] }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if frac_digits > 0 { // [0.][0000]
|
||||
if frac_digits > 0 {
|
||||
// [0.][0000]
|
||||
parts[0] = Part::Copy(b"0.");
|
||||
parts[1] = Part::Zero(frac_digits);
|
||||
Formatted { sign, parts: &parts[..2] }
|
||||
|
@ -430,8 +497,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
|
|||
}
|
||||
FullDecoded::Finite(ref decoded) => {
|
||||
let (len, exp) = format_shortest(decoded, buf);
|
||||
Formatted { sign,
|
||||
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
|
||||
Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -455,10 +521,19 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T,
|
|||
/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
|
||||
/// There should be at least 6 parts available, due to the worst case like
|
||||
/// `[+][1][.][2345][e][-][6]`.
|
||||
pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T,
|
||||
sign: Sign, dec_bounds: (i16, i16), upper: bool,
|
||||
buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
|
||||
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
|
||||
pub fn to_shortest_exp_str<'a, T, F>(
|
||||
mut format_shortest: F,
|
||||
v: T,
|
||||
sign: Sign,
|
||||
dec_bounds: (i16, i16),
|
||||
upper: bool,
|
||||
buf: &'a mut [u8],
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> Formatted<'a>
|
||||
where
|
||||
T: DecodableFloat,
|
||||
F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
|
||||
{
|
||||
assert!(parts.len() >= 6);
|
||||
assert!(buf.len() >= MAX_SIG_DIGITS);
|
||||
assert!(dec_bounds.0 <= dec_bounds.1);
|
||||
|
@ -534,10 +609,19 @@ fn estimate_max_buf_len(exp: i16) -> usize {
|
|||
/// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.)
|
||||
/// There should be at least 6 parts available, due to the worst case like
|
||||
/// `[+][1][.][2345][e][-][6]`.
|
||||
pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
|
||||
sign: Sign, ndigits: usize, upper: bool,
|
||||
buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
|
||||
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
|
||||
pub fn to_exact_exp_str<'a, T, F>(
|
||||
mut format_exact: F,
|
||||
v: T,
|
||||
sign: Sign,
|
||||
ndigits: usize,
|
||||
upper: bool,
|
||||
buf: &'a mut [u8],
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> Formatted<'a>
|
||||
where
|
||||
T: DecodableFloat,
|
||||
F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
|
||||
{
|
||||
assert!(parts.len() >= 6);
|
||||
assert!(ndigits > 0);
|
||||
|
||||
|
@ -553,7 +637,8 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
Formatted { sign, parts: &parts[..1] }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if ndigits > 1 { // [0.][0000][e0]
|
||||
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" });
|
||||
|
@ -569,8 +654,7 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
|
||||
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) }
|
||||
Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,10 +674,19 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
/// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.)
|
||||
/// There should be at least 4 parts available, due to the worst case like
|
||||
/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
|
||||
pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
|
||||
sign: Sign, frac_digits: usize, _upper: bool,
|
||||
buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
|
||||
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
|
||||
pub fn to_exact_fixed_str<'a, T, F>(
|
||||
mut format_exact: F,
|
||||
v: T,
|
||||
sign: Sign,
|
||||
frac_digits: usize,
|
||||
_upper: bool,
|
||||
buf: &'a mut [u8],
|
||||
parts: &'a mut [Part<'a>],
|
||||
) -> Formatted<'a>
|
||||
where
|
||||
T: DecodableFloat,
|
||||
F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
|
||||
{
|
||||
assert!(parts.len() >= 4);
|
||||
|
||||
let (negative, full_decoded) = decode(v);
|
||||
|
@ -608,7 +701,8 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
Formatted { sign, parts: &parts[..1] }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if frac_digits > 0 { // [0.][0000]
|
||||
if frac_digits > 0 {
|
||||
// [0.][0000]
|
||||
parts[0] = Part::Copy(b"0.");
|
||||
parts[1] = Part::Zero(frac_digits);
|
||||
Formatted { sign, parts: &parts[..2] }
|
||||
|
@ -631,7 +725,8 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
// `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);
|
||||
if frac_digits > 0 { // [0.][0000]
|
||||
if frac_digits > 0 {
|
||||
// [0.][0000]
|
||||
parts[0] = Part::Copy(b"0.");
|
||||
parts[1] = Part::Zero(frac_digits);
|
||||
Formatted { sign, parts: &parts[..2] }
|
||||
|
@ -640,8 +735,7 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
|
|||
Formatted { sign, parts: &parts[..1] }
|
||||
}
|
||||
} else {
|
||||
Formatted { sign,
|
||||
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
|
||||
Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,38 +6,54 @@
|
|||
|
||||
use crate::cmp::Ordering;
|
||||
|
||||
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
use crate::num::flt2dec::estimator::estimate_scaling_factor;
|
||||
use crate::num::bignum::Digit32 as Digit;
|
||||
use crate::num::bignum::Big32x40 as Big;
|
||||
use crate::num::bignum::Digit32 as Digit;
|
||||
use crate::num::flt2dec::estimator::estimate_scaling_factor;
|
||||
use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
|
||||
|
||||
static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000,
|
||||
1000000, 10000000, 100000000, 1000000000];
|
||||
static TWOPOW10: [Digit; 10] = [2, 20, 200, 2000, 20000, 200000,
|
||||
2000000, 20000000, 200000000, 2000000000];
|
||||
static POW10: [Digit; 10] =
|
||||
[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
|
||||
static TWOPOW10: [Digit; 10] =
|
||||
[2, 20, 200, 2000, 20000, 200000, 2000000, 20000000, 200000000, 2000000000];
|
||||
|
||||
// precalculated arrays of `Digit`s for 10^(2^n)
|
||||
static POW10TO16: [Digit; 2] = [0x6fc10000, 0x2386f2];
|
||||
static POW10TO32: [Digit; 4] = [0, 0x85acef81, 0x2d6d415b, 0x4ee];
|
||||
static POW10TO64: [Digit; 7] = [0, 0, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x184f03];
|
||||
static POW10TO128: [Digit; 14] =
|
||||
[0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08,
|
||||
0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x24e];
|
||||
static POW10TO256: [Digit; 27] =
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6,
|
||||
0xcf4a6e70, 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e,
|
||||
0xcc5573c0, 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7];
|
||||
static POW10TO128: [Digit; 14] = [
|
||||
0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da,
|
||||
0xa6337f19, 0xe91f2603, 0x24e,
|
||||
];
|
||||
static POW10TO256: [Digit; 27] = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
|
||||
0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17,
|
||||
0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7,
|
||||
];
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn mul_pow10(x: &mut Big, n: usize) -> &mut Big {
|
||||
debug_assert!(n < 512);
|
||||
if n & 7 != 0 { x.mul_small(POW10[n & 7]); }
|
||||
if n & 8 != 0 { x.mul_small(POW10[8]); }
|
||||
if n & 16 != 0 { x.mul_digits(&POW10TO16); }
|
||||
if n & 32 != 0 { x.mul_digits(&POW10TO32); }
|
||||
if n & 64 != 0 { x.mul_digits(&POW10TO64); }
|
||||
if n & 128 != 0 { x.mul_digits(&POW10TO128); }
|
||||
if n & 256 != 0 { x.mul_digits(&POW10TO256); }
|
||||
if n & 7 != 0 {
|
||||
x.mul_small(POW10[n & 7]);
|
||||
}
|
||||
if n & 8 != 0 {
|
||||
x.mul_small(POW10[8]);
|
||||
}
|
||||
if n & 16 != 0 {
|
||||
x.mul_digits(&POW10TO16);
|
||||
}
|
||||
if n & 32 != 0 {
|
||||
x.mul_digits(&POW10TO32);
|
||||
}
|
||||
if n & 64 != 0 {
|
||||
x.mul_digits(&POW10TO64);
|
||||
}
|
||||
if n & 128 != 0 {
|
||||
x.mul_digits(&POW10TO128);
|
||||
}
|
||||
if n & 256 != 0 {
|
||||
x.mul_digits(&POW10TO256);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
|
@ -52,13 +68,30 @@ fn div_2pow10(x: &mut Big, mut n: usize) -> &mut Big {
|
|||
}
|
||||
|
||||
// only usable when `x < 16 * scale`; `scaleN` should be `scale.mul_small(N)`
|
||||
fn div_rem_upto_16<'a>(x: &'a mut Big, scale: &Big,
|
||||
scale2: &Big, scale4: &Big, scale8: &Big) -> (u8, &'a mut Big) {
|
||||
fn div_rem_upto_16<'a>(
|
||||
x: &'a mut Big,
|
||||
scale: &Big,
|
||||
scale2: &Big,
|
||||
scale4: &Big,
|
||||
scale8: &Big,
|
||||
) -> (u8, &'a mut Big) {
|
||||
let mut d = 0;
|
||||
if *x >= *scale8 { x.sub(scale8); d += 8; }
|
||||
if *x >= *scale4 { x.sub(scale4); d += 4; }
|
||||
if *x >= *scale2 { x.sub(scale2); d += 2; }
|
||||
if *x >= *scale { x.sub(scale); d += 1; }
|
||||
if *x >= *scale8 {
|
||||
x.sub(scale8);
|
||||
d += 8;
|
||||
}
|
||||
if *x >= *scale4 {
|
||||
x.sub(scale4);
|
||||
d += 4;
|
||||
}
|
||||
if *x >= *scale2 {
|
||||
x.sub(scale2);
|
||||
d += 2;
|
||||
}
|
||||
if *x >= *scale {
|
||||
x.sub(scale);
|
||||
d += 1;
|
||||
}
|
||||
debug_assert!(*x < *scale);
|
||||
(d, x)
|
||||
}
|
||||
|
@ -132,9 +165,12 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
|
|||
}
|
||||
|
||||
// cache `(2, 4, 8) * scale` for digit generation.
|
||||
let mut scale2 = scale.clone(); scale2.mul_pow2(1);
|
||||
let mut scale4 = scale.clone(); scale4.mul_pow2(2);
|
||||
let mut scale8 = scale.clone(); scale8.mul_pow2(3);
|
||||
let mut scale2 = scale.clone();
|
||||
scale2.mul_pow2(1);
|
||||
let mut scale4 = scale.clone();
|
||||
scale4.mul_pow2(2);
|
||||
let mut scale8 = scale.clone();
|
||||
scale8.mul_pow2(3);
|
||||
|
||||
let mut down;
|
||||
let mut up;
|
||||
|
@ -186,7 +222,9 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
|
|||
// - keep generating otherwise.
|
||||
down = mant.cmp(&minus) < rounding;
|
||||
up = scale.cmp(mant.clone().add(&plus)) < rounding;
|
||||
if down || up { break; } // we have the shortest representation, proceed to the rounding
|
||||
if down || up {
|
||||
break;
|
||||
} // we have the shortest representation, proceed to the rounding
|
||||
|
||||
// restore the invariants.
|
||||
// this makes the algorithm always terminating: `minus` and `plus` always increases,
|
||||
|
@ -269,22 +307,40 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
|
|||
if len > 0 {
|
||||
// cache `(2, 4, 8) * scale` for digit generation.
|
||||
// (this can be expensive, so do not calculate them when the buffer is empty.)
|
||||
let mut scale2 = scale.clone(); scale2.mul_pow2(1);
|
||||
let mut scale4 = scale.clone(); scale4.mul_pow2(2);
|
||||
let mut scale8 = scale.clone(); scale8.mul_pow2(3);
|
||||
let mut scale2 = scale.clone();
|
||||
scale2.mul_pow2(1);
|
||||
let mut scale4 = scale.clone();
|
||||
scale4.mul_pow2(2);
|
||||
let mut scale8 = scale.clone();
|
||||
scale8.mul_pow2(3);
|
||||
|
||||
for i in 0..len {
|
||||
if mant.is_zero() { // following digits are all zeroes, we stop here
|
||||
if mant.is_zero() {
|
||||
// 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'; }
|
||||
for c in &mut buf[i..len] {
|
||||
*c = b'0';
|
||||
}
|
||||
return (len, k);
|
||||
}
|
||||
|
||||
let mut d = 0;
|
||||
if mant >= scale8 { mant.sub(&scale8); d += 8; }
|
||||
if mant >= scale4 { mant.sub(&scale4); d += 4; }
|
||||
if mant >= scale2 { mant.sub(&scale2); d += 2; }
|
||||
if mant >= scale { mant.sub(&scale); d += 1; }
|
||||
if mant >= scale8 {
|
||||
mant.sub(&scale8);
|
||||
d += 8;
|
||||
}
|
||||
if mant >= scale4 {
|
||||
mant.sub(&scale4);
|
||||
d += 4;
|
||||
}
|
||||
if mant >= scale2 {
|
||||
mant.sub(&scale2);
|
||||
d += 2;
|
||||
}
|
||||
if mant >= scale {
|
||||
mant.sub(&scale);
|
||||
d += 1;
|
||||
}
|
||||
debug_assert!(mant < scale);
|
||||
debug_assert!(d < 10);
|
||||
buf[i] = b'0' + d;
|
||||
|
@ -296,8 +352,9 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi
|
|||
// if the following digits are exactly 5000..., check the prior digit and try to
|
||||
// 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)) {
|
||||
if order == Ordering::Greater
|
||||
|| (order == Ordering::Equal && (len == 0 || buf[len - 1] & 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) {
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
//! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
|
||||
|
||||
use crate::num::diy_float::Fp;
|
||||
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
|
||||
|
||||
use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS};
|
||||
|
||||
// see the comments in `format_shortest_opt` for the rationale.
|
||||
#[doc(hidden)] pub const ALPHA: i16 = -60;
|
||||
#[doc(hidden)] pub const GAMMA: i16 = -32;
|
||||
#[doc(hidden)]
|
||||
pub const ALPHA: i16 = -60;
|
||||
#[doc(hidden)]
|
||||
pub const GAMMA: i16 = -32;
|
||||
|
||||
/*
|
||||
# the following Python code generates this table:
|
||||
|
@ -24,7 +25,8 @@ for i in xrange(-308, 333, 8):
|
|||
*/
|
||||
|
||||
#[doc(hidden)]
|
||||
pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k)
|
||||
pub static CACHED_POW10: [(u64, i16, i16); 81] = [
|
||||
// (f, e, k)
|
||||
(0xe61acf033d1a45df, -1087, -308),
|
||||
(0xab70fe17c79ac6ca, -1060, -300),
|
||||
(0xff77b1fcbebcdc4f, -1034, -292),
|
||||
|
@ -108,8 +110,10 @@ pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k)
|
|||
(0xeb96bf6ebadf77d9, 1039, 332),
|
||||
];
|
||||
|
||||
#[doc(hidden)] pub const CACHED_POW10_FIRST_E: i16 = -1087;
|
||||
#[doc(hidden)] pub const CACHED_POW10_LAST_E: i16 = 1039;
|
||||
#[doc(hidden)]
|
||||
pub const CACHED_POW10_FIRST_E: i16 = -1087;
|
||||
#[doc(hidden)]
|
||||
pub const CACHED_POW10_LAST_E: i16 = 1039;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn cached_power(alpha: i16, gamma: i16) -> (i16, Fp) {
|
||||
|
@ -138,20 +142,29 @@ pub fn max_pow10_no_more_than(x: u32) -> (u8, u32) {
|
|||
const X1: u32 = 10;
|
||||
|
||||
if x < X4 {
|
||||
if x < X2 { if x < X1 {(0, 1)} else {(1, X1)} }
|
||||
else { if x < X3 {(2, X2)} else {(3, X3)} }
|
||||
if x < X2 {
|
||||
if x < X1 { (0, 1) } else { (1, X1) }
|
||||
} else {
|
||||
if x < X6 { if x < X5 {(4, X4)} else {(5, X5)} }
|
||||
else if x < X8 { if x < X7 {(6, X6)} else {(7, X7)} }
|
||||
else { if x < X9 {(8, X8)} else {(9, X9)} }
|
||||
if x < X3 { (2, X2) } else { (3, X3) }
|
||||
}
|
||||
} else {
|
||||
if x < X6 {
|
||||
if x < X5 { (4, X4) } else { (5, X5) }
|
||||
} else if x < X8 {
|
||||
if x < X7 { (6, X6) } else { (7, X7) }
|
||||
} else {
|
||||
if x < X9 { (8, X8) } else { (9, X9) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The shortest mode implementation for Grisu.
|
||||
///
|
||||
/// It returns `None` when it would return an inexact representation otherwise.
|
||||
pub fn format_shortest_opt(d: &Decoded,
|
||||
buf: &mut [u8]) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
|
||||
pub fn format_shortest_opt(
|
||||
d: &Decoded,
|
||||
buf: &mut [u8],
|
||||
) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
|
||||
assert!(d.mant > 0);
|
||||
assert!(d.minus > 0);
|
||||
assert!(d.plus > 0);
|
||||
|
@ -242,7 +255,8 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
let mut kappa = max_kappa as i16;
|
||||
let mut ten_kappa = max_ten_kappa; // 10^kappa
|
||||
let mut remainder = plus1int; // digits yet to be rendered
|
||||
loop { // we always have at least one digit to render, as `plus1 >= 10^kappa`
|
||||
loop {
|
||||
// we always have at least one digit to render, as `plus1 >= 10^kappa`
|
||||
// invariants:
|
||||
// - `delta1int <= remainder < 10^(kappa+1)`
|
||||
// - `plus1int = d[0..n-1] * 10^(kappa+1) + remainder`
|
||||
|
@ -281,7 +295,8 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
let mut remainder = plus1frac;
|
||||
let mut threshold = delta1frac;
|
||||
let mut ulp = 1;
|
||||
loop { // the next digit should be significant as we've tested that before breaking out
|
||||
loop {
|
||||
// the next digit should be significant as we've tested that before breaking out
|
||||
// invariants, where `m = max_kappa + 1` (# of digits in the integral part):
|
||||
// - `remainder < 2^e`
|
||||
// - `plus1frac * 10^(n-m) = d[m..n-1] * 2^e + remainder`
|
||||
|
@ -300,8 +315,15 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
|
||||
if r < threshold {
|
||||
let ten_kappa = 1 << e; // implicit divisor
|
||||
return round_and_weed(&mut buf[..i], exp, r, threshold,
|
||||
(plus1 - v.f) * ulp, ten_kappa, ulp);
|
||||
return round_and_weed(
|
||||
&mut buf[..i],
|
||||
exp,
|
||||
r,
|
||||
threshold,
|
||||
(plus1 - v.f) * ulp,
|
||||
ten_kappa,
|
||||
ulp,
|
||||
);
|
||||
}
|
||||
|
||||
// restore invariants
|
||||
|
@ -325,8 +347,15 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
// - `plus1v = (plus1 - v) * k` (and also, `threshold > plus1v` from prior invariants)
|
||||
// - `ten_kappa = 10^kappa * k`
|
||||
// - `ulp = 2^-e * k`
|
||||
fn round_and_weed(buf: &mut [u8], exp: i16, remainder: u64, threshold: u64, plus1v: u64,
|
||||
ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> {
|
||||
fn round_and_weed(
|
||||
buf: &mut [u8],
|
||||
exp: i16,
|
||||
remainder: u64,
|
||||
threshold: u64,
|
||||
plus1v: u64,
|
||||
ten_kappa: u64,
|
||||
ulp: u64,
|
||||
) -> Option<(usize, i16)> {
|
||||
assert!(!buf.is_empty());
|
||||
|
||||
// produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps.
|
||||
|
@ -381,10 +410,11 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
//
|
||||
// consequently, we should stop when `TC1 || TC2 || (TC3a && TC3b)`. the following is
|
||||
// equal to its inverse, `!TC1 && !TC2 && (!TC3a || !TC3b)`.
|
||||
while plus1w < plus1v_up &&
|
||||
threshold - plus1w >= ten_kappa &&
|
||||
(plus1w + ten_kappa < plus1v_up ||
|
||||
plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up) {
|
||||
while plus1w < plus1v_up
|
||||
&& threshold - plus1w >= ten_kappa
|
||||
&& (plus1w + ten_kappa < plus1v_up
|
||||
|| plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up)
|
||||
{
|
||||
*last -= 1;
|
||||
debug_assert!(*last > b'0'); // the shortest repr cannot end with `0`
|
||||
plus1w += ten_kappa;
|
||||
|
@ -395,10 +425,11 @@ pub fn format_shortest_opt(d: &Decoded,
|
|||
//
|
||||
// this is simply same to the terminating conditions for `v + 1 ulp`, with all `plus1v_up`
|
||||
// replaced by `plus1v_down` instead. overflow analysis equally holds.
|
||||
if plus1w < plus1v_down &&
|
||||
threshold - plus1w >= ten_kappa &&
|
||||
(plus1w + ten_kappa < plus1v_down ||
|
||||
plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down) {
|
||||
if plus1w < plus1v_down
|
||||
&& threshold - plus1w >= ten_kappa
|
||||
&& (plus1w + ten_kappa < plus1v_down
|
||||
|| plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -428,8 +459,11 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp
|
|||
/// The exact and fixed mode implementation for Grisu.
|
||||
///
|
||||
/// It returns `None` when it would return an inexact representation otherwise.
|
||||
pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
|
||||
-> Option<(/*#digits*/ usize, /*exp*/ i16)> {
|
||||
pub fn format_exact_opt(
|
||||
d: &Decoded,
|
||||
buf: &mut [u8],
|
||||
limit: i16,
|
||||
) -> Option<(/*#digits*/ usize, /*exp*/ i16)> {
|
||||
assert!(d.mant > 0);
|
||||
assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision
|
||||
assert!(!buf.is_empty());
|
||||
|
@ -489,7 +523,8 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
|
|||
let mut kappa = max_kappa as i16;
|
||||
let mut ten_kappa = max_ten_kappa; // 10^kappa
|
||||
let mut remainder = vint; // digits yet to be rendered
|
||||
loop { // we always have at least one digit to render
|
||||
loop {
|
||||
// we always have at least one digit to render
|
||||
// invariants:
|
||||
// - `remainder < 10^(kappa+1)`
|
||||
// - `vint = d[0..n-1] * 10^(kappa+1) + remainder`
|
||||
|
@ -575,8 +610,15 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
|
|||
// - `remainder = (v % 10^kappa) * k`
|
||||
// - `ten_kappa = 10^kappa * k`
|
||||
// - `ulp = 2^-e * k`
|
||||
fn possibly_round(buf: &mut [u8], mut len: usize, mut exp: i16, limit: i16,
|
||||
remainder: u64, ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> {
|
||||
fn possibly_round(
|
||||
buf: &mut [u8],
|
||||
mut len: usize,
|
||||
mut exp: i16,
|
||||
limit: i16,
|
||||
remainder: u64,
|
||||
ten_kappa: u64,
|
||||
ulp: u64,
|
||||
) -> Option<(usize, i16)> {
|
||||
debug_assert!(remainder < ten_kappa);
|
||||
|
||||
// 10^kappa
|
||||
|
@ -593,7 +635,9 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
|
|||
//
|
||||
// error is too large that there are at least three possible representations
|
||||
// between `v - 1 ulp` and `v + 1 ulp`. we cannot determine which one is correct.
|
||||
if ulp >= ten_kappa { return None; }
|
||||
if ulp >= ten_kappa {
|
||||
return None;
|
||||
}
|
||||
|
||||
// 10^kappa
|
||||
// :<------->:
|
||||
|
@ -607,7 +651,9 @@ pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16)
|
|||
// in fact, 1/2 ulp is enough to introduce two possible representations.
|
||||
// (remember that we need a unique representation for both `v - 1 ulp` and `v + 1 ulp`.)
|
||||
// this won't overflow, as `ulp < ten_kappa` from the first check.
|
||||
if ten_kappa - ulp <= ulp { return None; }
|
||||
if ten_kappa - ulp <= ulp {
|
||||
return None;
|
||||
}
|
||||
|
||||
// remainder
|
||||
// :<->| :
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::ops::*;
|
|||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! sh_impl_signed {
|
||||
($t:ident, $f:ident) => (
|
||||
($t:ident, $f:ident) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shl<$f> for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
@ -54,11 +54,11 @@ macro_rules! sh_impl_signed {
|
|||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! sh_impl_unsigned {
|
||||
($t:ident, $f:ident) => (
|
||||
($t:ident, $f:ident) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shl<$f> for Wrapping<$t> {
|
||||
type Output = Wrapping<$t>;
|
||||
|
@ -100,7 +100,7 @@ macro_rules! sh_impl_unsigned {
|
|||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME (#23545): uncomment the remaining impls
|
||||
|
|
|
@ -66,16 +66,10 @@
|
|||
#[lang = "add"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(
|
||||
on(
|
||||
all(_Self="{integer}", Rhs="{float}"),
|
||||
message="cannot add a float to an integer",
|
||||
),
|
||||
on(
|
||||
all(_Self="{float}", Rhs="{integer}"),
|
||||
message="cannot add an integer to a float",
|
||||
),
|
||||
on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
|
||||
on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
|
||||
message = "cannot add `{Rhs}` to `{Self}`",
|
||||
label="no implementation for `{Self} + {Rhs}`",
|
||||
label = "no implementation for `{Self} + {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "+")]
|
||||
pub trait Add<Rhs = Self> {
|
||||
|
@ -173,8 +167,10 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "sub"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="cannot subtract `{Rhs}` from `{Self}`",
|
||||
label="no implementation for `{Self} - {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot subtract `{Rhs}` from `{Self}`",
|
||||
label = "no implementation for `{Self} - {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "-")]
|
||||
pub trait Sub<Rhs = Self> {
|
||||
/// The resulting type after applying the `-` operator.
|
||||
|
@ -293,8 +289,10 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "mul"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="cannot multiply `{Rhs}` to `{Self}`",
|
||||
label="no implementation for `{Self} * {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot multiply `{Rhs}` to `{Self}`",
|
||||
label = "no implementation for `{Self} * {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "*")]
|
||||
pub trait Mul<Rhs = Self> {
|
||||
/// The resulting type after applying the `*` operator.
|
||||
|
@ -417,8 +415,10 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "div"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{Rhs}`",
|
||||
label="no implementation for `{Self} / {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot divide `{Self}` by `{Rhs}`",
|
||||
label = "no implementation for `{Self} / {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "/")]
|
||||
pub trait Div<Rhs = Self> {
|
||||
/// The resulting type after applying the `/` operator.
|
||||
|
@ -502,8 +502,10 @@ div_impl_float! { f32 f64 }
|
|||
/// ```
|
||||
#[lang = "rem"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{Rhs}`",
|
||||
label="no implementation for `{Self} % {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot mod `{Self}` by `{Rhs}`",
|
||||
label = "no implementation for `{Self} % {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "%")]
|
||||
pub trait Rem<Rhs = Self> {
|
||||
/// The resulting type after applying the `%` operator.
|
||||
|
@ -534,7 +536,6 @@ macro_rules! rem_impl_integer {
|
|||
|
||||
rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||
|
||||
|
||||
macro_rules! rem_impl_float {
|
||||
($($t:ty)*) => ($(
|
||||
|
||||
|
@ -616,8 +617,6 @@ pub trait Neg {
|
|||
fn neg(self) -> Self::Output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro_rules! neg_impl_core {
|
||||
($id:ident => $body:expr, $($t:ty)*) => ($(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -679,8 +678,10 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "add_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`",
|
||||
label="no implementation for `{Self} += {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot add-assign `{Rhs}` to `{Self}`",
|
||||
label = "no implementation for `{Self} += {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "+")]
|
||||
#[doc(alias = "+=")]
|
||||
pub trait AddAssign<Rhs = Self> {
|
||||
|
@ -735,8 +736,10 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "sub_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="cannot subtract-assign `{Rhs}` from `{Self}`",
|
||||
label="no implementation for `{Self} -= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot subtract-assign `{Rhs}` from `{Self}`",
|
||||
label = "no implementation for `{Self} -= {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "-")]
|
||||
#[doc(alias = "-=")]
|
||||
pub trait SubAssign<Rhs = Self> {
|
||||
|
@ -782,8 +785,10 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "mul_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`",
|
||||
label="no implementation for `{Self} *= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot multiply-assign `{Rhs}` to `{Self}`",
|
||||
label = "no implementation for `{Self} *= {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "*")]
|
||||
#[doc(alias = "*=")]
|
||||
pub trait MulAssign<Rhs = Self> {
|
||||
|
@ -829,8 +834,10 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "div_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`",
|
||||
label="no implementation for `{Self} /= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot divide-assign `{Self}` by `{Rhs}`",
|
||||
label = "no implementation for `{Self} /= {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "/")]
|
||||
#[doc(alias = "/=")]
|
||||
pub trait DivAssign<Rhs = Self> {
|
||||
|
@ -879,8 +886,10 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
#[lang = "rem_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``",
|
||||
label="no implementation for `{Self} %= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "cannot mod-assign `{Self}` by `{Rhs}``",
|
||||
label = "no implementation for `{Self} %= {Rhs}`"
|
||||
)]
|
||||
#[doc(alias = "%")]
|
||||
#[doc(alias = "%=")]
|
||||
pub trait RemAssign<Rhs = Self> {
|
||||
|
|
|
@ -112,8 +112,10 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "bitand"]
|
||||
#[doc(alias = "&")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} & {Rhs}`",
|
||||
label="no implementation for `{Self} & {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} & {Rhs}`",
|
||||
label = "no implementation for `{Self} & {Rhs}`"
|
||||
)]
|
||||
pub trait BitAnd<Rhs = Self> {
|
||||
/// The resulting type after applying the `&` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -196,8 +198,10 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "bitor"]
|
||||
#[doc(alias = "|")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} | {Rhs}`",
|
||||
label="no implementation for `{Self} | {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} | {Rhs}`",
|
||||
label = "no implementation for `{Self} | {Rhs}`"
|
||||
)]
|
||||
pub trait BitOr<Rhs = Self> {
|
||||
/// The resulting type after applying the `|` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -283,8 +287,10 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "bitxor"]
|
||||
#[doc(alias = "^")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {Rhs}`",
|
||||
label="no implementation for `{Self} ^ {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} ^ {Rhs}`",
|
||||
label = "no implementation for `{Self} ^ {Rhs}`"
|
||||
)]
|
||||
pub trait BitXor<Rhs = Self> {
|
||||
/// The resulting type after applying the `^` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -371,8 +377,10 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "shl"]
|
||||
#[doc(alias = "<<")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} << {Rhs}`",
|
||||
label="no implementation for `{Self} << {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} << {Rhs}`",
|
||||
label = "no implementation for `{Self} << {Rhs}`"
|
||||
)]
|
||||
pub trait Shl<Rhs = Self> {
|
||||
/// The resulting type after applying the `<<` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -385,7 +393,7 @@ pub trait Shl<Rhs=Self> {
|
|||
}
|
||||
|
||||
macro_rules! shl_impl {
|
||||
($t:ty, $f:ty) => (
|
||||
($t:ty, $f:ty) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shl<$f> for $t {
|
||||
type Output = $t;
|
||||
|
@ -398,7 +406,7 @@ macro_rules! shl_impl {
|
|||
}
|
||||
|
||||
forward_ref_binop! { impl Shl, shl for $t, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! shl_impl_all {
|
||||
|
@ -480,8 +488,10 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
|||
#[lang = "shr"]
|
||||
#[doc(alias = ">>")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} >> {Rhs}`",
|
||||
label="no implementation for `{Self} >> {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} >> {Rhs}`",
|
||||
label = "no implementation for `{Self} >> {Rhs}`"
|
||||
)]
|
||||
pub trait Shr<Rhs = Self> {
|
||||
/// The resulting type after applying the `>>` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -494,7 +504,7 @@ pub trait Shr<Rhs=Self> {
|
|||
}
|
||||
|
||||
macro_rules! shr_impl {
|
||||
($t:ty, $f:ty) => (
|
||||
($t:ty, $f:ty) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shr<$f> for $t {
|
||||
type Output = $t;
|
||||
|
@ -507,7 +517,7 @@ macro_rules! shr_impl {
|
|||
}
|
||||
|
||||
forward_ref_binop! { impl Shr, shr for $t, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! shr_impl_all {
|
||||
|
@ -596,8 +606,10 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
#[lang = "bitand_assign"]
|
||||
#[doc(alias = "&=")]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`",
|
||||
label="no implementation for `{Self} &= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} &= {Rhs}`",
|
||||
label = "no implementation for `{Self} &= {Rhs}`"
|
||||
)]
|
||||
pub trait BitAndAssign<Rhs = Self> {
|
||||
/// Performs the `&=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
|
@ -645,8 +657,10 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "bitor_assign"]
|
||||
#[doc(alias = "|=")]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`",
|
||||
label="no implementation for `{Self} |= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} |= {Rhs}`",
|
||||
label = "no implementation for `{Self} |= {Rhs}`"
|
||||
)]
|
||||
pub trait BitOrAssign<Rhs = Self> {
|
||||
/// Performs the `|=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
|
@ -694,8 +708,10 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "bitxor_assign"]
|
||||
#[doc(alias = "^=")]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`",
|
||||
label="no implementation for `{Self} ^= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} ^= {Rhs}`",
|
||||
label = "no implementation for `{Self} ^= {Rhs}`"
|
||||
)]
|
||||
pub trait BitXorAssign<Rhs = Self> {
|
||||
/// Performs the `^=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
|
@ -741,8 +757,10 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
#[lang = "shl_assign"]
|
||||
#[doc(alias = "<<=")]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`",
|
||||
label="no implementation for `{Self} <<= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} <<= {Rhs}`",
|
||||
label = "no implementation for `{Self} <<= {Rhs}`"
|
||||
)]
|
||||
pub trait ShlAssign<Rhs = Self> {
|
||||
/// Performs the `<<=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
|
@ -750,7 +768,7 @@ pub trait ShlAssign<Rhs=Self> {
|
|||
}
|
||||
|
||||
macro_rules! shl_assign_impl {
|
||||
($t:ty, $f:ty) => (
|
||||
($t:ty, $f:ty) => {
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShlAssign<$f> for $t {
|
||||
#[inline]
|
||||
|
@ -761,7 +779,7 @@ macro_rules! shl_assign_impl {
|
|||
}
|
||||
|
||||
forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! shl_assign_impl_all {
|
||||
|
@ -809,8 +827,10 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
#[lang = "shr_assign"]
|
||||
#[doc(alias = ">>=")]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`",
|
||||
label="no implementation for `{Self} >>= {Rhs}`")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "no implementation for `{Self} >>= {Rhs}`",
|
||||
label = "no implementation for `{Self} >>= {Rhs}`"
|
||||
)]
|
||||
pub trait ShrAssign<Rhs = Self> {
|
||||
/// Performs the `>>=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
|
@ -818,7 +838,7 @@ pub trait ShrAssign<Rhs=Self> {
|
|||
}
|
||||
|
||||
macro_rules! shr_assign_impl {
|
||||
($t:ty, $f:ty) => (
|
||||
($t:ty, $f:ty) => {
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
impl ShrAssign<$f> for $t {
|
||||
#[inline]
|
||||
|
@ -829,7 +849,7 @@ macro_rules! shr_assign_impl {
|
|||
}
|
||||
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! shr_assign_impl_all {
|
||||
|
|
|
@ -76,14 +76,18 @@ pub trait Deref {
|
|||
impl<T: ?Sized> Deref for &T {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T { *self }
|
||||
fn deref(&self) -> &T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Deref for &mut T {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T { *self }
|
||||
fn deref(&self) -> &T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
/// Used for mutable dereferencing operations, like in `*v = 1;`.
|
||||
|
@ -165,7 +169,9 @@ pub trait DerefMut: Deref {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> DerefMut for &mut T {
|
||||
fn deref_mut(&mut self) -> &mut T { *self }
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that a struct can be used as a method receiver, without the
|
||||
|
|
|
@ -57,9 +57,12 @@
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_paren_sugar]
|
||||
#[rustc_on_unimplemented(
|
||||
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
|
||||
on(
|
||||
Args = "()",
|
||||
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
|
||||
),
|
||||
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
|
||||
label="expected an `Fn<{Args}>` closure, found `{Self}`",
|
||||
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
|
@ -136,9 +139,12 @@ pub trait Fn<Args> : FnMut<Args> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_paren_sugar]
|
||||
#[rustc_on_unimplemented(
|
||||
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
|
||||
on(
|
||||
Args = "()",
|
||||
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
|
||||
),
|
||||
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
|
||||
label="expected an `FnMut<{Args}>` closure, found `{Self}`",
|
||||
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
|
@ -207,9 +213,12 @@ pub trait FnMut<Args> : FnOnce<Args> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_paren_sugar]
|
||||
#[rustc_on_unimplemented(
|
||||
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
|
||||
on(
|
||||
Args = "()",
|
||||
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"
|
||||
),
|
||||
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
|
||||
label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
|
||||
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
|
||||
)]
|
||||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
|
@ -226,7 +235,8 @@ pub trait FnOnce<Args> {
|
|||
mod impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, F: ?Sized> Fn<A> for &F
|
||||
where F : Fn<A>
|
||||
where
|
||||
F: Fn<A>,
|
||||
{
|
||||
extern "rust-call" fn call(&self, args: A) -> F::Output {
|
||||
(**self).call(args)
|
||||
|
@ -235,7 +245,8 @@ mod impls {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, F: ?Sized> FnMut<A> for &F
|
||||
where F : Fn<A>
|
||||
where
|
||||
F: Fn<A>,
|
||||
{
|
||||
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
||||
(**self).call(args)
|
||||
|
@ -244,7 +255,8 @@ mod impls {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, F: ?Sized> FnOnce<A> for &F
|
||||
where F : Fn<A>
|
||||
where
|
||||
F: Fn<A>,
|
||||
{
|
||||
type Output = F::Output;
|
||||
|
||||
|
@ -255,7 +267,8 @@ mod impls {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, F: ?Sized> FnMut<A> for &mut F
|
||||
where F : FnMut<A>
|
||||
where
|
||||
F: FnMut<A>,
|
||||
{
|
||||
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
|
||||
(*self).call_mut(args)
|
||||
|
@ -264,7 +277,8 @@ mod impls {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A, F: ?Sized> FnOnce<A> for &mut F
|
||||
where F : FnMut<A>
|
||||
where
|
||||
F: FnMut<A>,
|
||||
{
|
||||
type Output = F::Output;
|
||||
extern "rust-call" fn call_once(self, args: A) -> F::Output {
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#[lang = "index"]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "the type `{Self}` cannot be indexed by `{Idx}`",
|
||||
label="`{Self}` cannot be indexed by `{Idx}`",
|
||||
label = "`{Self}` cannot be indexed by `{Idx}`"
|
||||
)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(alias = "]")]
|
||||
|
@ -157,7 +157,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
|
|||
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
|
||||
),
|
||||
message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
|
||||
label="`{Self}` cannot be mutably indexed by `{Idx}`",
|
||||
label = "`{Self}` cannot be mutably indexed by `{Idx}`"
|
||||
)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(alias = "[")]
|
||||
|
|
|
@ -156,12 +156,12 @@ mod r#try;
|
|||
mod unsize;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::arith::{Add, Sub, Mul, Div, Rem, Neg};
|
||||
pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
pub use self::arith::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||
pub use self::arith::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::bit::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
|
||||
pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
|
||||
|
||||
|
@ -184,7 +184,7 @@ pub use self::index::{Index, IndexMut};
|
|||
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
|
||||
|
||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||
pub use self::range::{RangeInclusive, RangeToInclusive, RangeBounds, Bound};
|
||||
pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
|
||||
|
||||
#[unstable(feature = "try_trait", issue = "42327")]
|
||||
pub use self::r#try::Try;
|
||||
|
|
|
@ -399,11 +399,7 @@ impl<Idx> RangeInclusive<Idx> {
|
|||
#[inline]
|
||||
#[rustc_promotable]
|
||||
pub const fn new(start: Idx, end: Idx) -> Self {
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
is_empty: None,
|
||||
}
|
||||
Self { start, end, is_empty: None }
|
||||
}
|
||||
|
||||
/// Returns the lower bound of the range (inclusive).
|
||||
|
|
|
@ -68,7 +68,6 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
|
|||
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
|
||||
|
||||
|
||||
/// This is used for object safety, to check that a method's receiver type can be dispatched on.
|
||||
///
|
||||
/// An example implementation of the trait:
|
||||
|
|
|
@ -138,8 +138,11 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::iter::{FromIterator, FusedIterator, TrustedLen};
|
||||
use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}};
|
||||
use crate::pin::Pin;
|
||||
use crate::{
|
||||
convert, fmt, hint, mem,
|
||||
ops::{self, Deref, DerefMut},
|
||||
};
|
||||
|
||||
// Note that this is not a lang item per se, but it has a hidden dependency on
|
||||
// `Iterator`, which is one. The compiler assumes that the `next` method of
|
||||
|
@ -230,7 +233,10 @@ impl<T> Option<T> {
|
|||
#[must_use]
|
||||
#[inline]
|
||||
#[unstable(feature = "option_result_contains", issue = "62358")]
|
||||
pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
|
||||
pub fn contains<U>(&self, x: &U) -> bool
|
||||
where
|
||||
U: PartialEq<T>,
|
||||
{
|
||||
match self {
|
||||
Some(y) => x == y,
|
||||
None => false,
|
||||
|
@ -291,16 +297,13 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Converts from [`Pin`]`<&Option<T>>` to `Option<`[`Pin`]`<&T>>`.
|
||||
///
|
||||
/// [`Pin`]: ../pin/struct.Pin.html
|
||||
#[inline]
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
|
||||
unsafe {
|
||||
Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
|
||||
}
|
||||
unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
|
||||
}
|
||||
|
||||
/// Converts from [`Pin`]`<&mut Option<T>>` to `Option<`[`Pin`]`<&mut T>>`.
|
||||
|
@ -309,9 +312,7 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
|
||||
unsafe {
|
||||
Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x))
|
||||
}
|
||||
unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) }
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -690,7 +691,7 @@ impl<T> Option<T> {
|
|||
pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
|
||||
if let Some(x) = self {
|
||||
if predicate(&x) {
|
||||
return Some(x)
|
||||
return Some(x);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -1228,7 +1229,9 @@ impl<T> Default for Option<T> {
|
|||
/// assert!(opt.is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn default() -> Option<T> { None }
|
||||
fn default() -> Option<T> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1302,7 +1305,7 @@ impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Item<A> {
|
||||
opt: Option<A>
|
||||
opt: Option<A>,
|
||||
}
|
||||
|
||||
impl<A> Iterator for Item<A> {
|
||||
|
@ -1344,22 +1347,30 @@ unsafe impl<A> TrustedLen for Item<A> {}
|
|||
/// [`Option::iter`]: enum.Option.html#method.iter
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct Iter<'a, A: 'a> { inner: Item<&'a A> }
|
||||
pub struct Iter<'a, A: 'a> {
|
||||
inner: Item<&'a A>,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, A> Iterator for Iter<'a, A> {
|
||||
type Item = &'a A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a A> { self.inner.next() }
|
||||
fn next(&mut self) -> Option<&'a A> {
|
||||
self.inner.next()
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() }
|
||||
fn next_back(&mut self) -> Option<&'a A> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1390,22 +1401,30 @@ impl<A> Clone for Iter<'_, A> {
|
|||
/// [`Option::iter_mut`]: enum.Option.html#method.iter_mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> }
|
||||
pub struct IterMut<'a, A: 'a> {
|
||||
inner: Item<&'a mut A>,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, A> Iterator for IterMut<'a, A> {
|
||||
type Item = &'a mut A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
|
||||
fn next(&mut self) -> Option<&'a mut A> {
|
||||
self.inner.next()
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() }
|
||||
fn next_back(&mut self) -> Option<&'a mut A> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1427,22 +1446,30 @@ unsafe impl<A> TrustedLen for IterMut<'_, A> {}
|
|||
/// [`Option::into_iter`]: enum.Option.html#method.into_iter
|
||||
#[derive(Clone, Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IntoIter<A> { inner: Item<A> }
|
||||
pub struct IntoIter<A> {
|
||||
inner: Item<A>,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A> Iterator for IntoIter<A> {
|
||||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> { self.inner.next() }
|
||||
fn next(&mut self) -> Option<A> {
|
||||
self.inner.next()
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A> DoubleEndedIterator for IntoIter<A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> { self.inner.next_back() }
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
self.inner.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1527,10 +1554,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
|
|||
// FIXME(#11084): This could be replaced with Iterator::scan when this
|
||||
// performance bug is closed.
|
||||
|
||||
iter.into_iter()
|
||||
.map(|x| x.ok_or(()))
|
||||
.collect::<Result<_, _>>()
|
||||
.ok()
|
||||
iter.into_iter().map(|x| x.ok_or(())).collect::<Result<_, _>>().ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -374,10 +374,10 @@
|
|||
|
||||
#![stable(feature = "pin", since = "1.33.0")]
|
||||
|
||||
use crate::cmp::{self, PartialEq, PartialOrd};
|
||||
use crate::fmt;
|
||||
use crate::marker::{Sized, Unpin};
|
||||
use crate::cmp::{self, PartialEq, PartialOrd};
|
||||
use crate::ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn};
|
||||
use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
|
||||
|
||||
/// A pinned pointer.
|
||||
///
|
||||
|
@ -646,7 +646,8 @@ impl<'a, T: ?Sized> Pin<&'a T> {
|
|||
///
|
||||
/// [`pin` module]: ../../std/pin/index.html#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
|
||||
pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>
|
||||
where
|
||||
F: FnOnce(&T) -> &U,
|
||||
{
|
||||
let pointer = &*self.pointer;
|
||||
|
@ -698,7 +699,8 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
|||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
#[inline(always)]
|
||||
pub fn get_mut(self) -> &'a mut T
|
||||
where T: Unpin,
|
||||
where
|
||||
T: Unpin,
|
||||
{
|
||||
self.pointer
|
||||
}
|
||||
|
@ -735,7 +737,8 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
|
|||
///
|
||||
/// [`pin` module]: ../../std/pin/index.html#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
|
||||
pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
|
||||
where
|
||||
F: FnOnce(&mut T) -> &mut U,
|
||||
{
|
||||
let pointer = Pin::get_unchecked_mut(self);
|
||||
|
@ -789,13 +792,7 @@ impl<P: fmt::Pointer> fmt::Pointer for Pin<P> {
|
|||
// for other reasons, though, so we just need to take care not to allow such
|
||||
// impls to land in std.
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
impl<P, U> CoerceUnsized<Pin<U>> for Pin<P>
|
||||
where
|
||||
P: CoerceUnsized<U>,
|
||||
{}
|
||||
impl<P, U> CoerceUnsized<Pin<U>> for Pin<P> where P: CoerceUnsized<U> {}
|
||||
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P>
|
||||
where
|
||||
P: DispatchFromDyn<U>,
|
||||
{}
|
||||
impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
|
||||
|
|
|
@ -25,25 +25,25 @@ pub use crate::mem::drop;
|
|||
pub use crate::clone::Clone;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::cmp::{PartialEq, PartialOrd, Eq, Ord};
|
||||
pub use crate::cmp::{Eq, Ord, PartialEq, PartialOrd};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::convert::{AsRef, AsMut, Into, From};
|
||||
pub use crate::convert::{AsMut, AsRef, From, Into};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::default::Default;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::iter::{Iterator, Extend, IntoIterator};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::iter::{DoubleEndedIterator, ExactSizeIterator};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::option::Option::{self, Some, None};
|
||||
pub use crate::iter::{Extend, IntoIterator, Iterator};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::result::Result::{self, Ok, Err};
|
||||
pub use crate::option::Option::{self, None, Some};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::result::Result::{self, Err, Ok};
|
||||
|
||||
// Re-exported built-in macros
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
|
@ -56,37 +56,14 @@ pub use crate::hash::macros::Hash;
|
|||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::{
|
||||
asm,
|
||||
assert,
|
||||
cfg,
|
||||
column,
|
||||
compile_error,
|
||||
concat,
|
||||
concat_idents,
|
||||
env,
|
||||
file,
|
||||
format_args,
|
||||
format_args_nl,
|
||||
global_asm,
|
||||
include,
|
||||
include_bytes,
|
||||
include_str,
|
||||
line,
|
||||
log_syntax,
|
||||
module_path,
|
||||
option_env,
|
||||
stringify,
|
||||
trace_macros,
|
||||
asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
|
||||
format_args_nl, global_asm, include, include_bytes, include_str, line, log_syntax, module_path,
|
||||
option_env, stringify, trace_macros,
|
||||
};
|
||||
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow(deprecated)]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::macros::builtin::{
|
||||
RustcDecodable,
|
||||
RustcEncodable,
|
||||
bench,
|
||||
global_allocator,
|
||||
test,
|
||||
test_case,
|
||||
bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::cmp::Ordering;
|
||||
use crate::convert::From;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::fmt;
|
||||
use crate::hash;
|
||||
use crate::marker::Unsize;
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::ptr::Unique;
|
||||
use crate::cmp::Ordering;
|
||||
|
||||
// ignore-tidy-undocumented-unsafe
|
||||
|
||||
|
@ -91,11 +91,7 @@ impl<T: ?Sized> NonNull<T> {
|
|||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||
if !ptr.is_null() {
|
||||
Some(unsafe { Self::new_unchecked(ptr) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None }
|
||||
}
|
||||
|
||||
/// Acquires the underlying `*mut` pointer.
|
||||
|
@ -131,9 +127,7 @@ impl<T: ?Sized> NonNull<T> {
|
|||
#[stable(feature = "nonnull_cast", since = "1.27.0")]
|
||||
#[inline]
|
||||
pub const fn cast<U>(self) -> NonNull<U> {
|
||||
unsafe {
|
||||
NonNull::new_unchecked(self.as_ptr() as *mut U)
|
||||
}
|
||||
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::convert::From;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::fmt;
|
||||
use crate::marker::{PhantomData, Unsize};
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
// ignore-tidy-undocumented-unsafe
|
||||
|
@ -27,9 +27,12 @@ use crate::ptr::NonNull;
|
|||
///
|
||||
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
|
||||
/// for any type which upholds Unique's aliasing requirements.
|
||||
#[unstable(feature = "ptr_internals", issue = "0",
|
||||
#[unstable(
|
||||
feature = "ptr_internals",
|
||||
issue = "0",
|
||||
reason = "use `NonNull` instead and consider `PhantomData<T>` \
|
||||
(if you also use `#[may_dangle]`), `Send`, and/or `Sync`")]
|
||||
(if you also use `#[may_dangle]`), `Send`, and/or `Sync`"
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
|
@ -71,9 +74,7 @@ impl<T: Sized> Unique<T> {
|
|||
// FIXME: rename to dangling() to match NonNull?
|
||||
#[inline]
|
||||
pub const fn empty() -> Self {
|
||||
unsafe {
|
||||
Unique::new_unchecked(mem::align_of::<T>() as *mut T)
|
||||
}
|
||||
unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,9 +129,7 @@ impl<T: ?Sized> Unique<T> {
|
|||
/// Casts to a pointer of another type.
|
||||
#[inline]
|
||||
pub const fn cast<U>(self) -> Unique<U> {
|
||||
unsafe {
|
||||
Unique::new_unchecked(self.as_ptr() as *mut U)
|
||||
}
|
||||
unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,16 @@ struct CopyOnDrop<T> {
|
|||
|
||||
impl<T> Drop for CopyOnDrop<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { ptr::copy_nonoverlapping(self.src, self.dest, 1); }
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(self.src, self.dest, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Shifts the first element to the right until it encounters a greater or equal element.
|
||||
fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
let len = v.len();
|
||||
unsafe {
|
||||
|
@ -36,10 +39,7 @@ fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
|
|||
// operation panics, `hole` will get dropped and automatically write the element back
|
||||
// into the slice.
|
||||
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(0)));
|
||||
let mut hole = CopyOnDrop {
|
||||
src: &mut *tmp,
|
||||
dest: v.get_unchecked_mut(1),
|
||||
};
|
||||
let mut hole = CopyOnDrop { src: &mut *tmp, dest: v.get_unchecked_mut(1) };
|
||||
ptr::copy_nonoverlapping(v.get_unchecked(1), v.get_unchecked_mut(0), 1);
|
||||
|
||||
for i in 2..len {
|
||||
|
@ -58,7 +58,8 @@ fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
|
|||
|
||||
/// Shifts the last element to the left until it encounters a smaller or equal element.
|
||||
fn shift_tail<T, F>(v: &mut [T], is_less: &mut F)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
let len = v.len();
|
||||
unsafe {
|
||||
|
@ -68,10 +69,7 @@ fn shift_tail<T, F>(v: &mut [T], is_less: &mut F)
|
|||
// operation panics, `hole` will get dropped and automatically write the element back
|
||||
// into the slice.
|
||||
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(len - 1)));
|
||||
let mut hole = CopyOnDrop {
|
||||
src: &mut *tmp,
|
||||
dest: v.get_unchecked_mut(len - 2),
|
||||
};
|
||||
let mut hole = CopyOnDrop { src: &mut *tmp, dest: v.get_unchecked_mut(len - 2) };
|
||||
ptr::copy_nonoverlapping(v.get_unchecked(len - 2), v.get_unchecked_mut(len - 1), 1);
|
||||
|
||||
for i in (0..len - 2).rev() {
|
||||
|
@ -93,7 +91,8 @@ fn shift_tail<T, F>(v: &mut [T], is_less: &mut F)
|
|||
/// Returns `true` if the slice is sorted at the end. This function is `O(n)` worst-case.
|
||||
#[cold]
|
||||
fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Maximum number of adjacent out-of-order pairs that will get shifted.
|
||||
const MAX_STEPS: usize = 5;
|
||||
|
@ -136,7 +135,8 @@ fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
|
|||
|
||||
/// Sorts a slice using insertion sort, which is `O(n^2)` worst-case.
|
||||
fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
for i in 1..v.len() {
|
||||
shift_tail(&mut v[..i + 1], is_less);
|
||||
|
@ -146,7 +146,8 @@ fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
|
|||
/// 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)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// This binary heap respects the invariant `parent >= child`.
|
||||
let mut sift_down = |v: &mut [T], mut node| {
|
||||
|
@ -156,11 +157,8 @@ pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
|
|||
let right = 2 * node + 2;
|
||||
|
||||
// Choose the greater child.
|
||||
let greater = if right < v.len() && is_less(&v[left], &v[right]) {
|
||||
right
|
||||
} else {
|
||||
left
|
||||
};
|
||||
let greater =
|
||||
if right < v.len() && is_less(&v[left], &v[right]) { right } else { left };
|
||||
|
||||
// Stop if the invariant holds at `node`.
|
||||
if greater >= v.len() || !is_less(&v[node], &v[greater]) {
|
||||
|
@ -195,7 +193,8 @@ pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
|
|||
///
|
||||
/// [pdf]: http://drops.dagstuhl.de/opus/volltexte/2016/6389/pdf/LIPIcs-ESA-2016-38.pdf
|
||||
fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Number of elements in a typical block.
|
||||
const BLOCK: usize = 128;
|
||||
|
@ -298,8 +297,16 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
|
|||
let count = cmp::min(width(start_l, end_l), width(start_r, end_r));
|
||||
|
||||
if count > 0 {
|
||||
macro_rules! left { () => { l.offset(*start_l as isize) } }
|
||||
macro_rules! right { () => { r.offset(-(*start_r as isize) - 1) } }
|
||||
macro_rules! left {
|
||||
() => {
|
||||
l.offset(*start_l as isize)
|
||||
};
|
||||
}
|
||||
macro_rules! right {
|
||||
() => {
|
||||
r.offset(-(*start_r as isize) - 1)
|
||||
};
|
||||
}
|
||||
|
||||
// Instead of swapping one pair at the time, it is more efficient to perform a cyclic
|
||||
// permutation. This is not strictly equivalent to swapping, but produces a similar
|
||||
|
@ -379,7 +386,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
|
|||
/// 1. Number of elements smaller than `v[pivot]`.
|
||||
/// 2. True if `v` was already partitioned.
|
||||
fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
let (mid, was_partitioned) = {
|
||||
// Place the pivot at the beginning of slice.
|
||||
|
@ -390,10 +398,7 @@ fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
|
|||
// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
|
||||
// operation panics, the pivot will be automatically written back into the slice.
|
||||
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
|
||||
let _pivot_guard = CopyOnDrop {
|
||||
src: &mut *tmp,
|
||||
dest: pivot,
|
||||
};
|
||||
let _pivot_guard = CopyOnDrop { src: &mut *tmp, dest: pivot };
|
||||
let pivot = &*tmp;
|
||||
|
||||
// Find the first pair of out-of-order elements.
|
||||
|
@ -429,7 +434,8 @@ fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
|
|||
/// Returns the number of elements equal to the pivot. It is assumed that `v` does not contain
|
||||
/// elements smaller than the pivot.
|
||||
fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Place the pivot at the beginning of slice.
|
||||
v.swap(0, pivot);
|
||||
|
@ -439,10 +445,7 @@ fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
|
|||
// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
|
||||
// operation panics, the pivot will be automatically written back into the slice.
|
||||
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
|
||||
let _pivot_guard = CopyOnDrop {
|
||||
src: &mut *tmp,
|
||||
dest: pivot,
|
||||
};
|
||||
let _pivot_guard = CopyOnDrop { src: &mut *tmp, dest: pivot };
|
||||
let pivot = &*tmp;
|
||||
|
||||
// Now partition the slice.
|
||||
|
@ -528,7 +531,8 @@ fn break_patterns<T>(v: &mut [T]) {
|
|||
///
|
||||
/// Elements in `v` might be reordered in the process.
|
||||
fn choose_pivot<T, F>(v: &mut [T], is_less: &mut F) -> (usize, bool)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Minimum length to choose the median-of-medians method.
|
||||
// Shorter slices use the simple median-of-three method.
|
||||
|
@ -596,7 +600,8 @@ fn choose_pivot<T, F>(v: &mut [T], is_less: &mut F) -> (usize, bool)
|
|||
/// `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)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Slices of up to this length get sorted using insertion sort.
|
||||
const MAX_INSERTION: usize = 20;
|
||||
|
@ -681,7 +686,8 @@ fn recurse<'a, T, F>(mut v: &'a mut [T], is_less: &mut F, mut pred: Option<&'a T
|
|||
|
||||
/// Sorts `v` using pattern-defeating quicksort, which is `O(n log n)` worst-case.
|
||||
pub fn quicksort<T, F>(v: &mut [T], mut is_less: F)
|
||||
where F: FnMut(&T, &T) -> bool
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
// Sorting has no meaningful behavior on zero-sized types.
|
||||
if mem::size_of::<T>() == 0 {
|
||||
|
@ -694,8 +700,13 @@ pub fn quicksort<T, F>(v: &mut [T], mut is_less: F)
|
|||
recurse(v, &mut is_less, None, limit);
|
||||
}
|
||||
|
||||
fn partition_at_index_loop<'a, T, F>( mut v: &'a mut [T], mut index: usize, is_less: &mut F
|
||||
, mut pred: Option<&'a T>) where F: FnMut(&T, &T) -> bool
|
||||
fn partition_at_index_loop<'a, T, F>(
|
||||
mut v: &'a mut [T],
|
||||
mut index: usize,
|
||||
is_less: &mut F,
|
||||
mut pred: Option<&'a T>,
|
||||
) where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
loop {
|
||||
// For slices of up to this length it's probably faster to simply sort them.
|
||||
|
@ -749,11 +760,16 @@ fn partition_at_index_loop<'a, T, F>( mut v: &'a mut [T], mut index: usize, is_l
|
|||
}
|
||||
}
|
||||
|
||||
pub fn partition_at_index<T, F>(v: &mut [T], index: usize, mut is_less: F)
|
||||
-> (&mut [T], &mut T, &mut [T]) where F: FnMut(&T, &T) -> bool
|
||||
pub fn partition_at_index<T, F>(
|
||||
v: &mut [T],
|
||||
index: usize,
|
||||
mut is_less: F,
|
||||
) -> (&mut [T], &mut T, &mut [T])
|
||||
where
|
||||
F: FnMut(&T, &T) -> bool,
|
||||
{
|
||||
use cmp::Ordering::Less;
|
||||
use cmp::Ordering::Greater;
|
||||
use cmp::Ordering::Less;
|
||||
|
||||
if index >= v.len() {
|
||||
panic!("partition_at_index index {} greater than length of slice {}", index, v.len());
|
||||
|
@ -764,14 +780,20 @@ pub fn partition_at_index<T, F>(v: &mut [T], index: usize, mut is_less: F)
|
|||
} else if index == v.len() - 1 {
|
||||
// Find max element and place it in the last position of the array. We're free to use
|
||||
// `unwrap()` here because we know v must not be empty.
|
||||
let (max_index, _) = v.iter().enumerate().max_by(
|
||||
|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater }).unwrap();
|
||||
let (max_index, _) = v
|
||||
.iter()
|
||||
.enumerate()
|
||||
.max_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
|
||||
.unwrap();
|
||||
v.swap(max_index, index);
|
||||
} else if index == 0 {
|
||||
// Find min element and place it in the first position of the array. We're free to use
|
||||
// `unwrap()` here because we know v must not be empty.
|
||||
let (min_index, _) = v.iter().enumerate().min_by(
|
||||
|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater }).unwrap();
|
||||
let (min_index, _) = v
|
||||
.iter()
|
||||
.enumerate()
|
||||
.min_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
|
||||
.unwrap();
|
||||
v.swap(min_index, index);
|
||||
} else {
|
||||
partition_at_index_loop(v, index, &mut is_less, None);
|
||||
|
|
|
@ -8,4 +8,4 @@ pub use self::poll::Poll;
|
|||
|
||||
mod wake;
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable};
|
||||
pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
|
||||
|
|
|
@ -11,10 +11,7 @@ use crate::result::Result;
|
|||
pub enum Poll<T> {
|
||||
/// Represents that a value is immediately ready.
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
Ready(
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
T
|
||||
),
|
||||
Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
|
||||
|
||||
/// Represents that a value is not ready yet.
|
||||
///
|
||||
|
@ -29,7 +26,8 @@ impl<T> Poll<T> {
|
|||
/// Changes the ready value of this `Poll` with the closure provided.
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub fn map<U, F>(self, f: F) -> Poll<U>
|
||||
where F: FnOnce(T) -> U
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
match self {
|
||||
Poll::Ready(t) => Poll::Ready(f(t)),
|
||||
|
@ -59,7 +57,8 @@ impl<T, E> Poll<Result<T, E>> {
|
|||
/// Changes the success value of this `Poll` with the closure provided.
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
|
||||
where F: FnOnce(T) -> U
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
match self {
|
||||
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
|
||||
|
@ -71,7 +70,8 @@ impl<T, E> Poll<Result<T, E>> {
|
|||
/// Changes the error value of this `Poll` with the closure provided.
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
|
||||
where F: FnOnce(E) -> U
|
||||
where
|
||||
F: FnOnce(E) -> U,
|
||||
{
|
||||
match self {
|
||||
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
|
||||
|
@ -85,7 +85,8 @@ impl<T, E> Poll<Option<Result<T, E>>> {
|
|||
/// Changes the success value of this `Poll` with the closure provided.
|
||||
#[unstable(feature = "poll_map", issue = "63514")]
|
||||
pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
|
||||
where F: FnOnce(T) -> U
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
match self {
|
||||
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
|
||||
|
@ -98,7 +99,8 @@ impl<T, E> Poll<Option<Result<T, E>>> {
|
|||
/// Changes the error value of this `Poll` with the closure provided.
|
||||
#[unstable(feature = "poll_map", issue = "63514")]
|
||||
pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
|
||||
where F: FnOnce(E) -> U
|
||||
where
|
||||
F: FnOnce(E) -> U,
|
||||
{
|
||||
match self {
|
||||
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
|
||||
|
|
|
@ -40,10 +40,7 @@ impl RawWaker {
|
|||
#[rustc_promotable]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
|
||||
RawWaker {
|
||||
data,
|
||||
vtable,
|
||||
}
|
||||
RawWaker { data, vtable }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,12 +157,7 @@ impl RawWakerVTable {
|
|||
wake_by_ref: unsafe fn(*const ()),
|
||||
drop: unsafe fn(*const ()),
|
||||
) -> Self {
|
||||
Self {
|
||||
clone,
|
||||
wake,
|
||||
wake_by_ref,
|
||||
drop,
|
||||
}
|
||||
Self { clone, wake, wake_by_ref, drop }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,10 +180,7 @@ impl<'a> Context<'a> {
|
|||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
#[inline]
|
||||
pub fn from_waker(waker: &'a Waker) -> Self {
|
||||
Context {
|
||||
waker,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
Context { waker, _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Returns a reference to the `Waker` for the current task.
|
||||
|
@ -205,9 +194,7 @@ impl<'a> Context<'a> {
|
|||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl fmt::Debug for Context<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Context")
|
||||
.field("waker", &self.waker)
|
||||
.finish()
|
||||
f.debug_struct("Context").field("waker", &self.waker).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,9 +278,7 @@ impl Waker {
|
|||
#[inline]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
|
||||
Waker {
|
||||
waker,
|
||||
}
|
||||
Waker { waker }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
|
||||
//! ```
|
||||
|
||||
use crate::{fmt, u64};
|
||||
use crate::iter::Sum;
|
||||
use crate::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
|
||||
use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||
use crate::{fmt, u64};
|
||||
|
||||
const NANOS_PER_SEC: u32 = 1_000_000_000;
|
||||
const NANOS_PER_MILLI: u32 = 1_000_000;
|
||||
|
@ -131,8 +131,8 @@ impl Duration {
|
|||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
#[inline]
|
||||
pub fn new(secs: u64, nanos: u32) -> Duration {
|
||||
let secs = secs.checked_add((nanos / NANOS_PER_SEC) as u64)
|
||||
.expect("overflow in Duration::new");
|
||||
let secs =
|
||||
secs.checked_add((nanos / NANOS_PER_SEC) as u64).expect("overflow in Duration::new");
|
||||
let nanos = nanos % NANOS_PER_SEC;
|
||||
Duration { secs, nanos }
|
||||
}
|
||||
|
@ -252,7 +252,9 @@ impl Duration {
|
|||
/// [`subsec_nanos`]: #method.subsec_nanos
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
#[inline]
|
||||
pub const fn as_secs(&self) -> u64 { self.secs }
|
||||
pub const fn as_secs(&self) -> u64 {
|
||||
self.secs
|
||||
}
|
||||
|
||||
/// Returns the fractional part of this `Duration`, in whole milliseconds.
|
||||
///
|
||||
|
@ -271,7 +273,9 @@ impl Duration {
|
|||
/// ```
|
||||
#[stable(feature = "duration_extras", since = "1.27.0")]
|
||||
#[inline]
|
||||
pub const fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI }
|
||||
pub const fn subsec_millis(&self) -> u32 {
|
||||
self.nanos / NANOS_PER_MILLI
|
||||
}
|
||||
|
||||
/// Returns the fractional part of this `Duration`, in whole microseconds.
|
||||
///
|
||||
|
@ -290,7 +294,9 @@ impl Duration {
|
|||
/// ```
|
||||
#[stable(feature = "duration_extras", since = "1.27.0")]
|
||||
#[inline]
|
||||
pub const fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO }
|
||||
pub const fn subsec_micros(&self) -> u32 {
|
||||
self.nanos / NANOS_PER_MICRO
|
||||
}
|
||||
|
||||
/// Returns the fractional part of this `Duration`, in nanoseconds.
|
||||
///
|
||||
|
@ -309,7 +315,9 @@ impl Duration {
|
|||
/// ```
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
#[inline]
|
||||
pub const fn subsec_nanos(&self) -> u32 { self.nanos }
|
||||
pub const fn subsec_nanos(&self) -> u32 {
|
||||
self.nanos
|
||||
}
|
||||
|
||||
/// Returns the total number of whole milliseconds contained by this `Duration`.
|
||||
///
|
||||
|
@ -388,10 +396,7 @@ impl Duration {
|
|||
}
|
||||
}
|
||||
debug_assert!(nanos < NANOS_PER_SEC);
|
||||
Some(Duration {
|
||||
secs,
|
||||
nanos,
|
||||
})
|
||||
Some(Duration { secs, nanos })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -455,14 +460,11 @@ impl Duration {
|
|||
let total_nanos = self.nanos as u64 * rhs as u64;
|
||||
let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
|
||||
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
|
||||
if let Some(secs) = self.secs
|
||||
.checked_mul(rhs as u64)
|
||||
.and_then(|s| s.checked_add(extra_secs)) {
|
||||
if let Some(secs) =
|
||||
self.secs.checked_mul(rhs as u64).and_then(|s| s.checked_add(extra_secs))
|
||||
{
|
||||
debug_assert!(nanos < NANOS_PER_SEC);
|
||||
Some(Duration {
|
||||
secs,
|
||||
nanos,
|
||||
})
|
||||
Some(Duration { secs, nanos })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -549,8 +551,7 @@ impl Duration {
|
|||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn from_secs_f64(secs: f64) -> Duration {
|
||||
const MAX_NANOS_F64: f64 =
|
||||
((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
|
||||
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() {
|
||||
panic!("got non-finite value when converting float to duration");
|
||||
|
@ -584,8 +585,7 @@ impl Duration {
|
|||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn from_secs_f32(secs: f32) -> Duration {
|
||||
const MAX_NANOS_F32: f32 =
|
||||
((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32;
|
||||
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() {
|
||||
panic!("got non-finite value when converting float to duration");
|
||||
|
@ -799,9 +799,8 @@ macro_rules! sum_durations {
|
|||
let mut total_nanos: u64 = 0;
|
||||
|
||||
for entry in $iter {
|
||||
total_secs = total_secs
|
||||
.checked_add(entry.secs)
|
||||
.expect("overflow in iter::sum over durations");
|
||||
total_secs =
|
||||
total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
|
||||
total_nanos = match total_nanos.checked_add(entry.nanos as u64) {
|
||||
Some(n) => n,
|
||||
None => {
|
||||
|
@ -816,10 +815,7 @@ macro_rules! sum_durations {
|
|||
.checked_add(total_nanos / NANOS_PER_SEC as u64)
|
||||
.expect("overflow in iter::sum over durations");
|
||||
total_nanos = total_nanos % NANOS_PER_SEC as u64;
|
||||
Duration {
|
||||
secs: total_secs,
|
||||
nanos: total_nanos as u32,
|
||||
}
|
||||
Duration { secs: total_secs, nanos: total_nanos as u32 }
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -922,9 +918,7 @@ impl fmt::Debug for Duration {
|
|||
} else {
|
||||
// SAFETY: We are only writing ASCII digits into the buffer and it was
|
||||
// initialized with '0's, so it contains valid UTF8.
|
||||
let s = unsafe {
|
||||
crate::str::from_utf8_unchecked(&buf[..end])
|
||||
};
|
||||
let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
|
||||
|
||||
// If the user request a precision > 9, we pad '0's at the end.
|
||||
let w = f.precision().unwrap_or(pos);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// See src/libstd/primitive_docs.rs for documentation.
|
||||
|
||||
use crate::cmp::*;
|
||||
use crate::cmp::Ordering::*;
|
||||
use crate::cmp::*;
|
||||
|
||||
// macro for implementing n-ary tuple functions and operations
|
||||
macro_rules! tuple_impls {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue