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