2014-04-30 22:14:22 -07:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
|
// except according to those terms.
|
2014-07-21 15:57:14 -07:00
|
|
|
//
|
|
|
|
|
// ignore-lexer-test FIXME #15679
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
//! Numeric traits and functions for the built-in numeric types.
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
2014-10-27 15:37:07 -07:00
|
|
|
#![allow(missing_docs)]
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2015-02-19 15:14:48 +01:00
|
|
|
use self::wrapping::{OverflowingOps, WrappingOps};
|
|
|
|
|
|
2014-12-30 13:53:20 +11:00
|
|
|
use char::CharExt;
|
2014-04-30 22:14:22 -07:00
|
|
|
use clone::Clone;
|
2015-01-27 22:52:32 -08:00
|
|
|
use cmp::{PartialEq, Eq, PartialOrd, Ord};
|
|
|
|
|
use error::Error;
|
|
|
|
|
use fmt;
|
2014-11-15 17:02:38 +11:00
|
|
|
use intrinsics;
|
2014-11-06 09:32:37 -08:00
|
|
|
use iter::IteratorExt;
|
2015-01-07 11:33:42 +13:00
|
|
|
use marker::Copy;
|
2014-04-30 22:14:22 -07:00
|
|
|
use mem::size_of;
|
|
|
|
|
use ops::{Add, Sub, Mul, Div, Rem, Neg};
|
2015-01-07 11:58:31 -05:00
|
|
|
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
|
2015-01-27 22:52:32 -08:00
|
|
|
use option::Option::{self, Some, None};
|
|
|
|
|
use result::Result::{self, Ok, Err};
|
2015-01-01 23:53:35 -08:00
|
|
|
use str::{FromStr, StrExt};
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2015-01-09 16:10:57 +13:00
|
|
|
#[unstable(feature = "core", reason = "may be removed or relocated")]
|
|
|
|
|
pub mod wrapping;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// A built-in signed or unsigned integer.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-10 11:30:52 +11:00
|
|
|
pub trait Int
|
|
|
|
|
: Copy + Clone
|
|
|
|
|
+ NumCast
|
|
|
|
|
+ PartialOrd + Ord
|
|
|
|
|
+ PartialEq + Eq
|
2014-12-31 15:45:13 -05:00
|
|
|
+ Add<Output=Self>
|
|
|
|
|
+ Sub<Output=Self>
|
|
|
|
|
+ Mul<Output=Self>
|
|
|
|
|
+ Div<Output=Self>
|
|
|
|
|
+ Rem<Output=Self>
|
2015-01-02 22:56:24 -05:00
|
|
|
+ Not<Output=Self>
|
2014-12-31 15:45:13 -05:00
|
|
|
+ BitAnd<Output=Self>
|
|
|
|
|
+ BitOr<Output=Self>
|
|
|
|
|
+ BitXor<Output=Self>
|
2015-03-25 17:06:52 -07:00
|
|
|
+ Shl<usize, Output=Self>
|
|
|
|
|
+ Shr<usize, Output=Self>
|
2015-02-19 15:14:48 +01:00
|
|
|
+ WrappingOps
|
|
|
|
|
+ OverflowingOps
|
2014-11-10 11:30:52 +11:00
|
|
|
{
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the `0` value of this integer type.
|
2014-11-10 09:35:53 +11:00
|
|
|
// FIXME (#5527): Should be an associated constant
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "unsure about its place in the world")]
|
2014-11-10 09:35:53 +11:00
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the `1` value of this integer type.
|
2014-11-10 09:35:53 +11:00
|
|
|
// FIXME (#5527): Should be an associated constant
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "unsure about its place in the world")]
|
2014-11-10 09:35:53 +11:00
|
|
|
fn one() -> Self;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the smallest value that can be represented by this integer type.
|
2014-11-10 01:20:13 +11:00
|
|
|
// FIXME (#5527): Should be and associated constant
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "unsure about its place in the world")]
|
2014-11-10 01:20:13 +11:00
|
|
|
fn min_value() -> Self;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the largest value that can be represented by this integer type.
|
2014-11-10 01:20:13 +11:00
|
|
|
// FIXME (#5527): Should be and associated constant
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "unsure about its place in the world")]
|
2014-11-10 01:20:13 +11:00
|
|
|
fn max_value() -> Self;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the number of ones in the binary representation of `self`.
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// let n = 0b01001100u8;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// assert_eq!(n.count_ones(), 3);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn count_ones(self) -> u32;
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Returns the number of zeros in the binary representation of `self`.
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// let n = 0b01001100u8;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// assert_eq!(n.count_zeros(), 5);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn count_zeros(self) -> u32 {
|
2014-06-16 11:25:47 -07:00
|
|
|
(!self).count_ones()
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
2014-08-01 02:43:51 +02:00
|
|
|
/// Returns the number of leading zeros in the binary representation
|
2014-11-10 16:00:13 +11:00
|
|
|
/// of `self`.
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// let n = 0b0101000u16;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// assert_eq!(n.leading_zeros(), 10);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn leading_zeros(self) -> u32;
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-08-01 02:43:51 +02:00
|
|
|
/// Returns the number of trailing zeros in the binary representation
|
2014-11-10 16:00:13 +11:00
|
|
|
/// of `self`.
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// let n = 0b0101000u16;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-04-30 22:14:22 -07:00
|
|
|
/// assert_eq!(n.trailing_zeros(), 3);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn trailing_zeros(self) -> u32;
|
2014-06-12 21:19:17 -07:00
|
|
|
|
2014-06-16 11:25:47 -07:00
|
|
|
/// Shifts the bits to the left by a specified amount amount, `n`, wrapping
|
|
|
|
|
/// the truncated bits to the end of the resulting integer.
|
2014-06-12 21:19:17 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-12 21:19:17 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-12 21:19:17 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0x3456789ABCDEF012u64;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-06-12 21:19:17 -07:00
|
|
|
/// assert_eq!(n.rotate_left(12), m);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn rotate_left(self, n: u32) -> Self;
|
2014-06-12 21:19:17 -07:00
|
|
|
|
2014-06-16 11:25:47 -07:00
|
|
|
/// Shifts the bits to the right by a specified amount amount, `n`, wrapping
|
|
|
|
|
/// the truncated bits to the beginning of the resulting integer.
|
2014-06-12 21:19:17 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-12 21:19:17 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-12 21:19:17 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xDEF0123456789ABCu64;
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2014-06-12 21:19:17 -07:00
|
|
|
/// assert_eq!(n.rotate_right(12), m);
|
|
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn rotate_right(self, n: u32) -> Self;
|
2014-06-16 11:25:47 -07:00
|
|
|
|
|
|
|
|
/// Reverses the byte order of the integer.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-16 11:25:47 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xEFCDAB8967452301u64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.swap_bytes(), m);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
fn swap_bytes(self) -> Self;
|
|
|
|
|
|
2014-11-16 16:51:22 -08:00
|
|
|
/// Convert an integer from big endian to the target's endianness.
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are swapped.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-16 11:25:47 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(Int::from_be(n), n)
|
2014-06-16 11:25:47 -07:00
|
|
|
/// } else {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(Int::from_be(n), n.swap_bytes())
|
2014-06-16 11:25:47 -07:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
#[inline]
|
2014-06-17 15:47:31 -07:00
|
|
|
fn from_be(x: Self) -> Self {
|
2014-06-16 11:25:47 -07:00
|
|
|
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-16 16:51:22 -08:00
|
|
|
/// Convert an integer from little endian to the target's endianness.
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are swapped.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-16 11:25:47 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(Int::from_le(n), n)
|
2014-06-16 11:25:47 -07:00
|
|
|
/// } else {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(Int::from_le(n), n.swap_bytes())
|
2014-06-16 11:25:47 -07:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
#[inline]
|
2014-06-17 15:47:31 -07:00
|
|
|
fn from_le(x: Self) -> Self {
|
2014-06-16 11:25:47 -07:00
|
|
|
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Convert `self` to big endian from the target's endianness.
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are swapped.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-16 11:25:47 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(n.to_be(), n)
|
2014-06-16 11:25:47 -07:00
|
|
|
/// } else {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(n.to_be(), n.swap_bytes())
|
2014-06-16 11:25:47 -07:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
#[inline]
|
2014-06-17 15:47:31 -07:00
|
|
|
fn to_be(self) -> Self { // or not to be?
|
2014-06-16 11:25:47 -07:00
|
|
|
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Convert `self` to little endian from the target's endianness.
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are swapped.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-06-16 11:25:47 -07:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 16:26:10 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2014-06-16 11:25:47 -07:00
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(n.to_le(), n)
|
2014-06-16 11:25:47 -07:00
|
|
|
/// } else {
|
2014-06-17 15:47:31 -07:00
|
|
|
/// assert_eq!(n.to_le(), n.swap_bytes())
|
2014-06-16 11:25:47 -07:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
#[inline]
|
2014-06-17 15:47:31 -07:00
|
|
|
fn to_le(self) -> Self {
|
2014-06-16 11:25:47 -07:00
|
|
|
if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
2014-11-09 17:46:33 +11:00
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Checked integer addition. Computes `self + other`, returning `None` if
|
|
|
|
|
/// overflow occurred.
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 00:11:28 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u16.checked_add(65530), Some(65535));
|
|
|
|
|
/// assert_eq!(6u16.checked_add(65530), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_add(self, other: Self) -> Option<Self>;
|
|
|
|
|
|
2014-12-02 20:42:09 +01:00
|
|
|
/// Checked integer subtraction. Computes `self - other`, returning `None`
|
2014-11-10 16:00:13 +11:00
|
|
|
/// if underflow occurred.
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 00:11:28 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_sub(1), Some(-128));
|
|
|
|
|
/// assert_eq!((-128i8).checked_sub(1), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_sub(self, other: Self) -> Option<Self>;
|
|
|
|
|
|
2014-12-02 20:42:09 +01:00
|
|
|
/// Checked integer multiplication. Computes `self * other`, returning
|
2014-11-10 16:00:13 +11:00
|
|
|
/// `None` if underflow or overflow occurred.
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 00:11:28 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(51), Some(255));
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(52), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_mul(self, other: Self) -> Option<Self>;
|
|
|
|
|
|
2014-12-02 20:42:09 +01:00
|
|
|
/// Checked integer division. Computes `self / other`, returning `None` if
|
|
|
|
|
/// `other == 0` or the operation results in underflow or overflow.
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-11-10 00:11:28 +11:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2014-11-10 00:11:28 +11:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_div(-1), Some(127));
|
|
|
|
|
/// assert_eq!((-128i8).checked_div(-1), None);
|
|
|
|
|
/// assert_eq!((1i8).checked_div(0), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_div(self, other: Self) -> Option<Self>;
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Saturating integer addition. Computes `self + other`, saturating at
|
|
|
|
|
/// the numeric bounds instead of overflowing.
|
2015-03-10 11:33:10 -04:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u16.saturating_add(65534), 65535);
|
|
|
|
|
/// assert_eq!((-5i16).saturating_add(-32767), -32768);
|
|
|
|
|
/// assert_eq!(100u32.saturating_add(4294967294), 4294967295);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-09 17:46:33 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn saturating_add(self, other: Self) -> Self {
|
2014-11-10 00:11:28 +11:00
|
|
|
match self.checked_add(other) {
|
2014-11-10 09:35:53 +11:00
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= Int::zero() => Int::max_value(),
|
|
|
|
|
None => Int::min_value(),
|
2014-11-09 17:46:33 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// Saturating integer subtraction. Computes `self - other`, saturating at
|
|
|
|
|
/// the numeric bounds instead of overflowing.
|
2015-03-10 11:33:10 -04:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u16.saturating_sub(65534), 0);
|
|
|
|
|
/// assert_eq!(5i16.saturating_sub(-32767), 32767);
|
|
|
|
|
/// assert_eq!(100u32.saturating_sub(4294967294), 0);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-09 17:46:33 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn saturating_sub(self, other: Self) -> Self {
|
2014-11-10 00:11:28 +11:00
|
|
|
match self.checked_sub(other) {
|
2014-11-10 09:35:53 +11:00
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= Int::zero() => Int::min_value(),
|
|
|
|
|
None => Int::max_value(),
|
2014-11-09 17:46:33 +11:00
|
|
|
}
|
|
|
|
|
}
|
2014-11-17 22:12:54 +08:00
|
|
|
|
|
|
|
|
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-11-17 22:12:54 +08:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-11-17 22:12:54 +08:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
2015-01-22 14:08:56 +00:00
|
|
|
/// assert_eq!(2.pow(4), 16);
|
2014-11-17 22:12:54 +08:00
|
|
|
/// ```
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "pending integer conventions")]
|
2014-11-17 22:12:54 +08:00
|
|
|
#[inline]
|
2015-02-27 21:04:15 +01:00
|
|
|
fn pow(self, mut exp: u32) -> Self {
|
2014-11-17 22:12:54 +08:00
|
|
|
let mut base = self;
|
|
|
|
|
let mut acc: Self = Int::one();
|
2015-02-27 21:04:15 +01:00
|
|
|
|
2015-02-19 15:14:48 +01:00
|
|
|
let mut prev_base = self;
|
|
|
|
|
let mut base_oflo = false;
|
2014-11-17 22:12:54 +08:00
|
|
|
while exp > 0 {
|
|
|
|
|
if (exp & 1) == 1 {
|
2015-02-19 15:14:48 +01:00
|
|
|
if base_oflo {
|
|
|
|
|
// ensure overflow occurs in the same manner it
|
|
|
|
|
// would have otherwise (i.e. signal any exception
|
|
|
|
|
// it would have otherwise).
|
|
|
|
|
acc = acc * (prev_base * prev_base);
|
|
|
|
|
} else {
|
|
|
|
|
acc = acc * base;
|
|
|
|
|
}
|
2014-11-17 22:12:54 +08:00
|
|
|
}
|
2015-02-19 15:14:48 +01:00
|
|
|
prev_base = base;
|
|
|
|
|
let (new_base, new_base_oflo) = base.overflowing_mul(base);
|
|
|
|
|
base = new_base;
|
|
|
|
|
base_oflo = new_base_oflo;
|
2014-11-17 22:12:54 +08:00
|
|
|
exp /= 2;
|
|
|
|
|
}
|
|
|
|
|
acc
|
|
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
2014-11-10 00:11:28 +11:00
|
|
|
macro_rules! checked_op {
|
|
|
|
|
($T:ty, $U:ty, $op:path, $x:expr, $y:expr) => {{
|
|
|
|
|
let (result, overflowed) = unsafe { $op($x as $U, $y as $U) };
|
|
|
|
|
if overflowed { None } else { Some(result as $T) }
|
|
|
|
|
}}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-09 21:30:30 +11:00
|
|
|
macro_rules! uint_impl {
|
2014-11-10 00:11:28 +11:00
|
|
|
($T:ty = $ActualT:ty, $BITS:expr,
|
|
|
|
|
$ctpop:path,
|
|
|
|
|
$ctlz:path,
|
|
|
|
|
$cttz:path,
|
|
|
|
|
$bswap:path,
|
|
|
|
|
$add_with_overflow:path,
|
|
|
|
|
$sub_with_overflow:path,
|
|
|
|
|
$mul_with_overflow:path) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
impl Int for $T {
|
2014-11-10 09:35:53 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn zero() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn one() -> $T { 1 }
|
|
|
|
|
|
2014-11-10 01:20:13 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn min_value() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn max_value() -> $T { -1 }
|
|
|
|
|
|
2014-05-26 19:33:04 +02:00
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn count_ones(self) -> u32 {
|
|
|
|
|
unsafe { $ctpop(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn leading_zeros(self) -> u32 {
|
|
|
|
|
unsafe { $ctlz(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2014-06-12 21:19:17 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn trailing_zeros(self) -> u32 {
|
|
|
|
|
unsafe { $cttz(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2014-06-12 21:19:17 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn rotate_left(self, n: u32) -> $T {
|
2014-06-16 11:25:47 -07:00
|
|
|
// Protect against undefined behaviour for over-long bit shifts
|
|
|
|
|
let n = n % $BITS;
|
2014-07-02 04:58:23 +01:00
|
|
|
(self << n) | (self >> (($BITS - n) % $BITS))
|
2014-06-12 21:19:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn rotate_right(self, n: u32) -> $T {
|
2014-06-16 11:25:47 -07:00
|
|
|
// Protect against undefined behaviour for over-long bit shifts
|
|
|
|
|
let n = n % $BITS;
|
2014-07-02 04:58:23 +01:00
|
|
|
(self >> n) | (self << (($BITS - n) % $BITS))
|
2014-06-12 21:19:17 -07:00
|
|
|
}
|
2014-06-16 11:25:47 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn swap_bytes(self) -> $T {
|
|
|
|
|
unsafe { $bswap(self as $ActualT) as $T }
|
|
|
|
|
}
|
2014-11-10 00:11:28 +11:00
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn checked_add(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $add_with_overflow, self, other)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn checked_sub(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $sub_with_overflow, self, other)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn checked_mul(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $mul_with_overflow, self, other)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn checked_div(self, v: $T) -> Option<$T> {
|
|
|
|
|
match v {
|
|
|
|
|
0 => None,
|
|
|
|
|
v => Some(self / v),
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
2014-06-14 22:53:55 -07:00
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
|
2014-06-16 11:25:47 -07:00
|
|
|
/// Swapping a single byte is a no-op. This is marked as `unsafe` for
|
|
|
|
|
/// consistency with the other `bswap` intrinsics.
|
|
|
|
|
unsafe fn bswap8(x: u8) -> u8 { x }
|
|
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
uint_impl! { u8 = u8, 8,
|
2014-06-16 11:25:47 -07:00
|
|
|
intrinsics::ctpop8,
|
|
|
|
|
intrinsics::ctlz8,
|
|
|
|
|
intrinsics::cttz8,
|
2014-11-10 00:11:28 +11:00
|
|
|
bswap8,
|
|
|
|
|
intrinsics::u8_add_with_overflow,
|
|
|
|
|
intrinsics::u8_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u8_mul_with_overflow }
|
2014-06-16 11:25:47 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
uint_impl! { u16 = u16, 16,
|
2014-06-16 11:25:47 -07:00
|
|
|
intrinsics::ctpop16,
|
|
|
|
|
intrinsics::ctlz16,
|
|
|
|
|
intrinsics::cttz16,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::bswap16,
|
|
|
|
|
intrinsics::u16_add_with_overflow,
|
|
|
|
|
intrinsics::u16_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u16_mul_with_overflow }
|
2014-06-16 11:25:47 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
uint_impl! { u32 = u32, 32,
|
2014-06-16 11:25:47 -07:00
|
|
|
intrinsics::ctpop32,
|
|
|
|
|
intrinsics::ctlz32,
|
|
|
|
|
intrinsics::cttz32,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::bswap32,
|
|
|
|
|
intrinsics::u32_add_with_overflow,
|
|
|
|
|
intrinsics::u32_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u32_mul_with_overflow }
|
2014-06-16 11:25:47 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
uint_impl! { u64 = u64, 64,
|
2014-06-16 11:25:47 -07:00
|
|
|
intrinsics::ctpop64,
|
|
|
|
|
intrinsics::ctlz64,
|
|
|
|
|
intrinsics::cttz64,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::bswap64,
|
|
|
|
|
intrinsics::u64_add_with_overflow,
|
|
|
|
|
intrinsics::u64_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u64_mul_with_overflow }
|
2014-06-16 11:25:47 -07:00
|
|
|
|
2015-01-16 17:01:02 +02:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
2015-03-25 17:06:52 -07:00
|
|
|
uint_impl! { usize = u32, 32,
|
2014-11-09 21:30:30 +11:00
|
|
|
intrinsics::ctpop32,
|
|
|
|
|
intrinsics::ctlz32,
|
|
|
|
|
intrinsics::cttz32,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::bswap32,
|
|
|
|
|
intrinsics::u32_add_with_overflow,
|
|
|
|
|
intrinsics::u32_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u32_mul_with_overflow }
|
2014-11-09 21:30:30 +11:00
|
|
|
|
2015-01-16 17:01:02 +02:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2015-03-25 17:06:52 -07:00
|
|
|
uint_impl! { usize = u64, 64,
|
2014-11-09 21:30:30 +11:00
|
|
|
intrinsics::ctpop64,
|
|
|
|
|
intrinsics::ctlz64,
|
|
|
|
|
intrinsics::cttz64,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::bswap64,
|
|
|
|
|
intrinsics::u64_add_with_overflow,
|
|
|
|
|
intrinsics::u64_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::u64_mul_with_overflow }
|
2014-11-09 21:30:30 +11:00
|
|
|
|
|
|
|
|
macro_rules! int_impl {
|
2014-11-10 01:20:13 +11:00
|
|
|
($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
|
2014-11-10 00:11:28 +11:00
|
|
|
$add_with_overflow:path,
|
|
|
|
|
$sub_with_overflow:path,
|
|
|
|
|
$mul_with_overflow:path) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-16 11:25:47 -07:00
|
|
|
impl Int for $T {
|
2014-11-10 09:35:53 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn zero() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn one() -> $T { 1 }
|
|
|
|
|
|
2014-11-10 01:20:13 +11:00
|
|
|
#[inline]
|
|
|
|
|
fn min_value() -> $T { (-1 as $T) << ($BITS - 1) }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn max_value() -> $T { let min: $T = Int::min_value(); !min }
|
|
|
|
|
|
2014-05-26 19:33:04 +02:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn leading_zeros(self) -> u32 {
|
|
|
|
|
(self as $UnsignedT).leading_zeros()
|
|
|
|
|
}
|
2014-11-10 00:11:28 +11:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn trailing_zeros(self) -> u32 {
|
|
|
|
|
(self as $UnsignedT).trailing_zeros()
|
|
|
|
|
}
|
2014-11-10 00:11:28 +11:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn rotate_left(self, n: u32) -> $T {
|
|
|
|
|
(self as $UnsignedT).rotate_left(n) as $T
|
|
|
|
|
}
|
2014-06-12 21:19:17 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn rotate_right(self, n: u32) -> $T {
|
|
|
|
|
(self as $UnsignedT).rotate_right(n) as $T
|
|
|
|
|
}
|
2014-06-12 21:19:17 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-18 09:36:18 -07:00
|
|
|
fn swap_bytes(self) -> $T {
|
|
|
|
|
(self as $UnsignedT).swap_bytes() as $T
|
|
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
|
|
|
|
|
#[inline]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_add(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $add_with_overflow, self, other)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn checked_sub(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $sub_with_overflow, self, other)
|
|
|
|
|
}
|
2014-06-12 21:19:17 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_mul(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $mul_with_overflow, self, other)
|
|
|
|
|
}
|
2014-06-16 11:25:47 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2014-11-10 00:11:28 +11:00
|
|
|
fn checked_div(self, v: $T) -> Option<$T> {
|
|
|
|
|
match v {
|
|
|
|
|
0 => None,
|
2014-11-10 01:20:13 +11:00
|
|
|
-1 if self == Int::min_value()
|
2014-11-10 00:11:28 +11:00
|
|
|
=> None,
|
|
|
|
|
v => Some(self / v),
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
2014-06-14 22:53:55 -07:00
|
|
|
}
|
2014-05-26 19:33:04 +02:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
int_impl! { i8 = i8, u8, 8,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i8_add_with_overflow,
|
|
|
|
|
intrinsics::i8_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i8_mul_with_overflow }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
int_impl! { i16 = i16, u16, 16,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i16_add_with_overflow,
|
|
|
|
|
intrinsics::i16_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i16_mul_with_overflow }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
int_impl! { i32 = i32, u32, 32,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i32_add_with_overflow,
|
|
|
|
|
intrinsics::i32_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i32_mul_with_overflow }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
int_impl! { i64 = i64, u64, 64,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i64_add_with_overflow,
|
|
|
|
|
intrinsics::i64_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i64_mul_with_overflow }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
2015-01-16 17:01:02 +02:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
2015-03-25 17:06:52 -07:00
|
|
|
int_impl! { isize = i32, u32, 32,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i32_add_with_overflow,
|
|
|
|
|
intrinsics::i32_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i32_mul_with_overflow }
|
2014-11-10 00:11:28 +11:00
|
|
|
|
2015-01-16 17:01:02 +02:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2015-03-25 17:06:52 -07:00
|
|
|
int_impl! { isize = i64, u64, 64,
|
2014-11-10 00:11:28 +11:00
|
|
|
intrinsics::i64_add_with_overflow,
|
|
|
|
|
intrinsics::i64_sub_with_overflow,
|
2014-11-14 09:18:10 -08:00
|
|
|
intrinsics::i64_mul_with_overflow }
|
2014-05-26 19:33:04 +02:00
|
|
|
|
2014-11-13 00:02:42 +11:00
|
|
|
/// A built-in two's complement integer.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-13 00:02:42 +11:00
|
|
|
pub trait SignedInt
|
|
|
|
|
: Int
|
2015-01-02 22:56:24 -05:00
|
|
|
+ Neg<Output=Self>
|
2014-11-13 00:02:42 +11:00
|
|
|
{
|
|
|
|
|
/// Computes the absolute value of `self`. `Int::min_value()` will be
|
|
|
|
|
/// returned if the number is `Int::min_value()`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "overflow in debug builds?")]
|
2014-11-13 00:02:42 +11:00
|
|
|
fn abs(self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Returns a number representing sign of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// - `0` if the number is zero
|
|
|
|
|
/// - `1` if the number is positive
|
|
|
|
|
/// - `-1` if the number is negative
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-13 00:02:42 +11:00
|
|
|
fn signum(self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Returns `true` if `self` is positive and `false` if the number
|
|
|
|
|
/// is zero or negative.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-13 00:02:42 +11:00
|
|
|
fn is_positive(self) -> bool;
|
|
|
|
|
|
|
|
|
|
/// Returns `true` if `self` is negative and `false` if the number
|
|
|
|
|
/// is zero or positive.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-13 00:02:42 +11:00
|
|
|
fn is_negative(self) -> bool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! signed_int_impl {
|
|
|
|
|
($T:ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-13 00:02:42 +11:00
|
|
|
impl SignedInt for $T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn abs(self) -> $T {
|
|
|
|
|
if self.is_negative() { -self } else { self }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn signum(self) -> $T {
|
|
|
|
|
match self {
|
|
|
|
|
n if n > 0 => 1,
|
|
|
|
|
0 => 0,
|
|
|
|
|
_ => -1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn is_positive(self) -> bool { self > 0 }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn is_negative(self) -> bool { self < 0 }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
signed_int_impl! { i8 }
|
|
|
|
|
signed_int_impl! { i16 }
|
|
|
|
|
signed_int_impl! { i32 }
|
|
|
|
|
signed_int_impl! { i64 }
|
2015-03-25 17:06:52 -07:00
|
|
|
signed_int_impl! { isize }
|
2014-11-13 00:02:42 +11:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
// `Int` + `SignedInt` implemented for signed integers
|
|
|
|
|
macro_rules! int_impl {
|
|
|
|
|
($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
|
|
|
|
|
$add_with_overflow:path,
|
|
|
|
|
$sub_with_overflow:path,
|
|
|
|
|
$mul_with_overflow:path) => {
|
|
|
|
|
/// Returns the `0` value of this integer type.
|
|
|
|
|
// FIXME (#5527): Should be an associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn zero() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
/// Returns the `1` value of this integer type.
|
|
|
|
|
// FIXME (#5527): Should be an associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn one() -> $T { 1 }
|
|
|
|
|
|
|
|
|
|
/// Returns the smallest value that can be represented by this integer
|
|
|
|
|
/// type.
|
|
|
|
|
// FIXME (#5527): Should be and associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn min_value() -> $T { (-1 as $T) << ($BITS - 1) }
|
|
|
|
|
|
|
|
|
|
/// Returns the largest value that can be represented by this integer
|
|
|
|
|
/// type.
|
|
|
|
|
// FIXME (#5527): Should be and associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn max_value() -> $T { let min: $T = <$T>::min_value(); !min }
|
|
|
|
|
|
|
|
|
|
/// Returns the number of ones in the binary representation of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b01001100u8;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.count_ones(), 3);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
|
|
|
|
|
|
|
|
|
|
/// Returns the number of zeros in the binary representation of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b01001100u8;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.count_zeros(), 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn count_zeros(self) -> u32 {
|
|
|
|
|
(!self).count_ones()
|
2014-11-09 17:15:45 +11:00
|
|
|
}
|
2014-11-15 22:03:34 -08:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the number of leading zeros in the binary representation
|
|
|
|
|
/// of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b0101000u16;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.leading_zeros(), 10);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn leading_zeros(self) -> u32 {
|
|
|
|
|
(self as $UnsignedT).leading_zeros()
|
|
|
|
|
}
|
2014-11-15 22:03:34 -08:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the number of trailing zeros in the binary representation
|
|
|
|
|
/// of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b0101000u16;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.trailing_zeros(), 3);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn trailing_zeros(self) -> u32 {
|
|
|
|
|
(self as $UnsignedT).trailing_zeros()
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Shifts the bits to the left by a specified amount amount, `n`,
|
|
|
|
|
/// wrapping the truncated bits to the end of the resulting integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0x3456789ABCDEF012u64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.rotate_left(12), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn rotate_left(self, n: u32) -> $T {
|
|
|
|
|
(self as $UnsignedT).rotate_left(n) as $T
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Shifts the bits to the right by a specified amount amount, `n`,
|
|
|
|
|
/// wrapping the truncated bits to the beginning of the resulting
|
|
|
|
|
/// integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xDEF0123456789ABCu64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.rotate_right(12), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn rotate_right(self, n: u32) -> $T {
|
|
|
|
|
(self as $UnsignedT).rotate_right(n) as $T
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Reverses the byte order of the integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xEFCDAB8967452301u64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.swap_bytes(), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn swap_bytes(self) -> $T {
|
|
|
|
|
(self as $UnsignedT).swap_bytes() as $T
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert an integer from big endian to the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
|
|
|
|
/// assert_eq!(Int::from_be(n), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(Int::from_be(n), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_be(x: $T) -> $T {
|
|
|
|
|
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert an integer from little endian to the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
|
|
|
|
/// assert_eq!(Int::from_le(n), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(Int::from_le(n), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_le(x: $T) -> $T {
|
|
|
|
|
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert `self` to big endian from the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
|
|
|
|
/// assert_eq!(n.to_be(), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(n.to_be(), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn to_be(self) -> $T { // or not to be?
|
|
|
|
|
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert `self` to little endian from the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
|
|
|
|
/// assert_eq!(n.to_le(), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(n.to_le(), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn to_le(self) -> $T {
|
|
|
|
|
if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer addition. Computes `self + other`, returning `None`
|
|
|
|
|
/// if overflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u16.checked_add(65530), Some(65535));
|
|
|
|
|
/// assert_eq!(6u16.checked_add(65530), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_add(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $add_with_overflow, self, other)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer subtraction. Computes `self - other`, returning
|
|
|
|
|
/// `None` if underflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_sub(1), Some(-128));
|
|
|
|
|
/// assert_eq!((-128i8).checked_sub(1), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_sub(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $sub_with_overflow, self, other)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer multiplication. Computes `self * other`, returning
|
|
|
|
|
/// `None` if underflow or overflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(51), Some(255));
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(52), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_mul(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $mul_with_overflow, self, other)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer division. Computes `self / other`, returning `None`
|
|
|
|
|
/// if `other == 0` or the operation results in underflow or overflow.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_div(-1), Some(127));
|
|
|
|
|
/// assert_eq!((-128i8).checked_div(-1), None);
|
|
|
|
|
/// assert_eq!((1i8).checked_div(0), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_div(self, v: $T) -> Option<$T> {
|
|
|
|
|
match v {
|
|
|
|
|
0 => None,
|
|
|
|
|
-1 if self == <$T>::min_value()
|
|
|
|
|
=> None,
|
|
|
|
|
v => Some(self / v),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Saturating integer addition. Computes `self + other`, saturating at
|
|
|
|
|
/// the numeric bounds instead of overflowing.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn saturating_add(self, other: $T) -> $T {
|
|
|
|
|
match self.checked_add(other) {
|
|
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= <$T>::zero() => <$T>::max_value(),
|
|
|
|
|
None => <$T>::min_value(),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Saturating integer subtraction. Computes `self - other`, saturating
|
|
|
|
|
/// at the numeric bounds instead of overflowing.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn saturating_sub(self, other: $T) -> $T {
|
|
|
|
|
match self.checked_sub(other) {
|
|
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= <$T>::zero() => <$T>::min_value(),
|
|
|
|
|
None => <$T>::max_value(),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(2.pow(4), 16);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn pow(self, mut exp: u32) -> $T {
|
|
|
|
|
let mut base = self;
|
|
|
|
|
let mut acc = <$T>::one();
|
|
|
|
|
|
|
|
|
|
let mut prev_base = self;
|
|
|
|
|
let mut base_oflo = false;
|
|
|
|
|
while exp > 0 {
|
|
|
|
|
if (exp & 1) == 1 {
|
|
|
|
|
if base_oflo {
|
|
|
|
|
// ensure overflow occurs in the same manner it
|
|
|
|
|
// would have otherwise (i.e. signal any exception
|
|
|
|
|
// it would have otherwise).
|
|
|
|
|
acc = acc * (prev_base * prev_base);
|
|
|
|
|
} else {
|
|
|
|
|
acc = acc * base;
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
prev_base = base;
|
|
|
|
|
let (new_base, new_base_oflo) = base.overflowing_mul(base);
|
|
|
|
|
base = new_base;
|
|
|
|
|
base_oflo = new_base_oflo;
|
|
|
|
|
exp /= 2;
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
acc
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Computes the absolute value of `self`. `Int::min_value()` will be
|
|
|
|
|
/// returned if the number is `Int::min_value()`.
|
|
|
|
|
#[unstable(feature = "core", reason = "overflow in debug builds?")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn abs(self) -> $T {
|
|
|
|
|
if self.is_negative() { -self } else { self }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns a number representing sign of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// - `0` if the number is zero
|
|
|
|
|
/// - `1` if the number is positive
|
|
|
|
|
/// - `-1` if the number is negative
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn signum(self) -> $T {
|
|
|
|
|
match self {
|
|
|
|
|
n if n > 0 => 1,
|
|
|
|
|
0 => 0,
|
|
|
|
|
_ => -1,
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns `true` if `self` is positive and `false` if the number
|
|
|
|
|
/// is zero or negative.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn is_positive(self) -> bool { self > 0 }
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns `true` if `self` is negative and `false` if the number
|
|
|
|
|
/// is zero or positive.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn is_negative(self) -> bool { self < 0 }
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "i8"]
|
|
|
|
|
impl i8 {
|
|
|
|
|
int_impl! { i8 = i8, u8, 8,
|
|
|
|
|
intrinsics::i8_add_with_overflow,
|
|
|
|
|
intrinsics::i8_sub_with_overflow,
|
|
|
|
|
intrinsics::i8_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "i16"]
|
|
|
|
|
impl i16 {
|
|
|
|
|
int_impl! { i16 = i16, u16, 16,
|
|
|
|
|
intrinsics::i16_add_with_overflow,
|
|
|
|
|
intrinsics::i16_sub_with_overflow,
|
|
|
|
|
intrinsics::i16_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "i32"]
|
|
|
|
|
impl i32 {
|
|
|
|
|
int_impl! { i32 = i32, u32, 32,
|
|
|
|
|
intrinsics::i32_add_with_overflow,
|
|
|
|
|
intrinsics::i32_sub_with_overflow,
|
|
|
|
|
intrinsics::i32_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "i64"]
|
|
|
|
|
impl i64 {
|
|
|
|
|
int_impl! { i64 = i64, u64, 64,
|
|
|
|
|
intrinsics::i64_add_with_overflow,
|
|
|
|
|
intrinsics::i64_sub_with_overflow,
|
|
|
|
|
intrinsics::i64_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
|
|
|
|
#[lang = "isize"]
|
|
|
|
|
impl isize {
|
2015-03-25 17:06:52 -07:00
|
|
|
int_impl! { isize = i32, u32, 32,
|
2015-03-18 09:36:18 -07:00
|
|
|
intrinsics::i32_add_with_overflow,
|
|
|
|
|
intrinsics::i32_sub_with_overflow,
|
|
|
|
|
intrinsics::i32_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
|
|
|
|
#[lang = "isize"]
|
|
|
|
|
impl isize {
|
2015-03-25 17:06:52 -07:00
|
|
|
int_impl! { isize = i64, u64, 64,
|
2015-03-18 09:36:18 -07:00
|
|
|
intrinsics::i64_add_with_overflow,
|
|
|
|
|
intrinsics::i64_sub_with_overflow,
|
|
|
|
|
intrinsics::i64_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
// `Int` + `UnsignedInt` implemented for signed integers
|
|
|
|
|
macro_rules! uint_impl {
|
|
|
|
|
($T:ty = $ActualT:ty, $BITS:expr,
|
|
|
|
|
$ctpop:path,
|
|
|
|
|
$ctlz:path,
|
|
|
|
|
$cttz:path,
|
|
|
|
|
$bswap:path,
|
|
|
|
|
$add_with_overflow:path,
|
|
|
|
|
$sub_with_overflow:path,
|
|
|
|
|
$mul_with_overflow:path) => {
|
|
|
|
|
/// Returns the `0` value of this integer type.
|
|
|
|
|
// FIXME (#5527): Should be an associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn zero() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
/// Returns the `1` value of this integer type.
|
|
|
|
|
// FIXME (#5527): Should be an associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn one() -> $T { 1 }
|
|
|
|
|
|
|
|
|
|
/// Returns the smallest value that can be represented by this integer
|
|
|
|
|
/// type.
|
|
|
|
|
// FIXME (#5527): Should be and associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn min_value() -> $T { 0 }
|
|
|
|
|
|
|
|
|
|
/// Returns the largest value that can be represented by this integer
|
|
|
|
|
/// type.
|
|
|
|
|
// FIXME (#5527): Should be and associated constant
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "unsure about its place in the world")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn max_value() -> $T { -1 }
|
|
|
|
|
|
|
|
|
|
/// Returns the number of ones in the binary representation of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b01001100u8;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.count_ones(), 3);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn count_ones(self) -> u32 {
|
|
|
|
|
unsafe { $ctpop(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the number of zeros in the binary representation of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b01001100u8;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.count_zeros(), 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn count_zeros(self) -> u32 {
|
|
|
|
|
(!self).count_ones()
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the number of leading zeros in the binary representation
|
|
|
|
|
/// of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b0101000u16;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.leading_zeros(), 10);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn leading_zeros(self) -> u32 {
|
|
|
|
|
unsafe { $ctlz(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the number of trailing zeros in the binary representation
|
|
|
|
|
/// of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0b0101000u16;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.trailing_zeros(), 3);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn trailing_zeros(self) -> u32 {
|
|
|
|
|
unsafe { $cttz(self as $ActualT) as u32 }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Shifts the bits to the left by a specified amount amount, `n`,
|
|
|
|
|
/// wrapping the truncated bits to the end of the resulting integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0x3456789ABCDEF012u64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.rotate_left(12), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn rotate_left(self, n: u32) -> $T {
|
|
|
|
|
// Protect against undefined behaviour for over-long bit shifts
|
|
|
|
|
let n = n % $BITS;
|
|
|
|
|
(self << n) | (self >> (($BITS - n) % $BITS))
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Shifts the bits to the right by a specified amount amount, `n`,
|
|
|
|
|
/// wrapping the truncated bits to the beginning of the resulting
|
|
|
|
|
/// integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xDEF0123456789ABCu64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.rotate_right(12), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn rotate_right(self, n: u32) -> $T {
|
|
|
|
|
// Protect against undefined behaviour for over-long bit shifts
|
|
|
|
|
let n = n % $BITS;
|
|
|
|
|
(self >> n) | (self << (($BITS - n) % $BITS))
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Reverses the byte order of the integer.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
/// let m = 0xEFCDAB8967452301u64;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(n.swap_bytes(), m);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn swap_bytes(self) -> $T {
|
|
|
|
|
unsafe { $bswap(self as $ActualT) as $T }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert an integer from big endian to the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
|
|
|
|
/// assert_eq!(Int::from_be(n), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(Int::from_be(n), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_be(x: $T) -> $T {
|
|
|
|
|
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert an integer from little endian to the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
|
|
|
|
/// assert_eq!(Int::from_le(n), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(Int::from_le(n), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_le(x: $T) -> $T {
|
|
|
|
|
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert `self` to big endian from the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On big endian this is a no-op. On little endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "big") {
|
|
|
|
|
/// assert_eq!(n.to_be(), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(n.to_be(), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn to_be(self) -> $T { // or not to be?
|
|
|
|
|
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Convert `self` to little endian from the target's endianness.
|
|
|
|
|
///
|
|
|
|
|
/// On little endian this is a no-op. On big endian the bytes are
|
|
|
|
|
/// swapped.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// let n = 0x0123456789ABCDEFu64;
|
|
|
|
|
///
|
|
|
|
|
/// if cfg!(target_endian = "little") {
|
|
|
|
|
/// assert_eq!(n.to_le(), n)
|
|
|
|
|
/// } else {
|
|
|
|
|
/// assert_eq!(n.to_le(), n.swap_bytes())
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn to_le(self) -> $T {
|
|
|
|
|
if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer addition. Computes `self + other`, returning `None`
|
|
|
|
|
/// if overflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u16.checked_add(65530), Some(65535));
|
|
|
|
|
/// assert_eq!(6u16.checked_add(65530), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_add(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $add_with_overflow, self, other)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer subtraction. Computes `self - other`, returning
|
|
|
|
|
/// `None` if underflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_sub(1), Some(-128));
|
|
|
|
|
/// assert_eq!((-128i8).checked_sub(1), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_sub(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $sub_with_overflow, self, other)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Checked integer multiplication. Computes `self * other`, returning
|
|
|
|
|
/// `None` if underflow or overflow occurred.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(51), Some(255));
|
|
|
|
|
/// assert_eq!(5u8.checked_mul(52), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_mul(self, other: $T) -> Option<$T> {
|
|
|
|
|
checked_op!($T, $ActualT, $mul_with_overflow, self, other)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Checked integer division. Computes `self / other`, returning `None`
|
|
|
|
|
/// if `other == 0` or the operation results in underflow or overflow.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!((-127i8).checked_div(-1), Some(127));
|
|
|
|
|
/// assert_eq!((-128i8).checked_div(-1), None);
|
|
|
|
|
/// assert_eq!((1i8).checked_div(0), None);
|
|
|
|
|
/// ```
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn checked_div(self, v: $T) -> Option<$T> {
|
|
|
|
|
match v {
|
|
|
|
|
0 => None,
|
|
|
|
|
v => Some(self / v),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Saturating integer addition. Computes `self + other`, saturating at
|
|
|
|
|
/// the numeric bounds instead of overflowing.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn saturating_add(self, other: $T) -> $T {
|
|
|
|
|
match self.checked_add(other) {
|
|
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= <$T>::zero() => <$T>::max_value(),
|
|
|
|
|
None => <$T>::min_value(),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Saturating integer subtraction. Computes `self - other`, saturating
|
|
|
|
|
/// at the numeric bounds instead of overflowing.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn saturating_sub(self, other: $T) -> $T {
|
|
|
|
|
match self.checked_sub(other) {
|
|
|
|
|
Some(x) => x,
|
|
|
|
|
None if other >= <$T>::zero() => <$T>::min_value(),
|
|
|
|
|
None => <$T>::max_value(),
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2015-03-18 09:36:18 -07:00
|
|
|
/// use std::num::Int;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(2.pow(4), 16);
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "pending integer conventions")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn pow(self, mut exp: u32) -> $T {
|
|
|
|
|
let mut base = self;
|
|
|
|
|
let mut acc = <$T>::one();
|
|
|
|
|
|
|
|
|
|
let mut prev_base = self;
|
|
|
|
|
let mut base_oflo = false;
|
|
|
|
|
while exp > 0 {
|
|
|
|
|
if (exp & 1) == 1 {
|
|
|
|
|
if base_oflo {
|
|
|
|
|
// ensure overflow occurs in the same manner it
|
|
|
|
|
// would have otherwise (i.e. signal any exception
|
|
|
|
|
// it would have otherwise).
|
|
|
|
|
acc = acc * (prev_base * prev_base);
|
|
|
|
|
} else {
|
|
|
|
|
acc = acc * base;
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
prev_base = base;
|
|
|
|
|
let (new_base, new_base_oflo) = base.overflowing_mul(base);
|
|
|
|
|
base = new_base;
|
|
|
|
|
base_oflo = new_base_oflo;
|
|
|
|
|
exp /= 2;
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
acc
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns `true` iff `self == 2^k` for some `k`.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn is_power_of_two(self) -> bool {
|
|
|
|
|
(self.wrapping_sub(<$T>::one())) & self == <$T>::zero() &&
|
|
|
|
|
!(self == <$T>::zero())
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the smallest power of two greater than or equal to `self`.
|
|
|
|
|
/// Unspecified behavior on overflow.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn next_power_of_two(self) -> $T {
|
|
|
|
|
let bits = size_of::<$T>() * 8;
|
|
|
|
|
let one: $T = <$T>::one();
|
|
|
|
|
one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
/// Returns the smallest power of two greater than or equal to `n`. If
|
|
|
|
|
/// the next power of two is greater than the type's maximum value,
|
|
|
|
|
/// `None` is returned, otherwise the power of two is wrapped in `Some`.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub fn checked_next_power_of_two(self) -> Option<$T> {
|
|
|
|
|
let npot = self.next_power_of_two();
|
|
|
|
|
if npot >= self {
|
|
|
|
|
Some(npot)
|
|
|
|
|
} else {
|
|
|
|
|
None
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-18 09:36:18 -07:00
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "u8"]
|
|
|
|
|
impl u8 {
|
|
|
|
|
uint_impl! { u8 = u8, 8,
|
|
|
|
|
intrinsics::ctpop8,
|
|
|
|
|
intrinsics::ctlz8,
|
|
|
|
|
intrinsics::cttz8,
|
|
|
|
|
bswap8,
|
|
|
|
|
intrinsics::u8_add_with_overflow,
|
|
|
|
|
intrinsics::u8_sub_with_overflow,
|
|
|
|
|
intrinsics::u8_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "u16"]
|
|
|
|
|
impl u16 {
|
|
|
|
|
uint_impl! { u16 = u16, 16,
|
|
|
|
|
intrinsics::ctpop16,
|
|
|
|
|
intrinsics::ctlz16,
|
|
|
|
|
intrinsics::cttz16,
|
|
|
|
|
intrinsics::bswap16,
|
|
|
|
|
intrinsics::u16_add_with_overflow,
|
|
|
|
|
intrinsics::u16_sub_with_overflow,
|
|
|
|
|
intrinsics::u16_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "u32"]
|
|
|
|
|
impl u32 {
|
|
|
|
|
uint_impl! { u32 = u32, 32,
|
|
|
|
|
intrinsics::ctpop32,
|
|
|
|
|
intrinsics::ctlz32,
|
|
|
|
|
intrinsics::cttz32,
|
|
|
|
|
intrinsics::bswap32,
|
|
|
|
|
intrinsics::u32_add_with_overflow,
|
|
|
|
|
intrinsics::u32_sub_with_overflow,
|
|
|
|
|
intrinsics::u32_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
|
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[lang = "u64"]
|
|
|
|
|
impl u64 {
|
|
|
|
|
uint_impl! { u64 = u64, 64,
|
|
|
|
|
intrinsics::ctpop64,
|
|
|
|
|
intrinsics::ctlz64,
|
|
|
|
|
intrinsics::cttz64,
|
|
|
|
|
intrinsics::bswap64,
|
|
|
|
|
intrinsics::u64_add_with_overflow,
|
|
|
|
|
intrinsics::u64_sub_with_overflow,
|
|
|
|
|
intrinsics::u64_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
|
|
|
|
#[lang = "usize"]
|
|
|
|
|
impl usize {
|
2015-03-25 17:06:52 -07:00
|
|
|
uint_impl! { usize = u32, 32,
|
2015-03-18 09:36:18 -07:00
|
|
|
intrinsics::ctpop32,
|
|
|
|
|
intrinsics::ctlz32,
|
|
|
|
|
intrinsics::cttz32,
|
|
|
|
|
intrinsics::bswap32,
|
|
|
|
|
intrinsics::u32_add_with_overflow,
|
|
|
|
|
intrinsics::u32_sub_with_overflow,
|
|
|
|
|
intrinsics::u32_mul_with_overflow }
|
|
|
|
|
}
|
2015-03-10 23:13:40 -05:00
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
|
|
|
|
#[lang = "usize"]
|
|
|
|
|
impl usize {
|
2015-03-25 17:06:52 -07:00
|
|
|
uint_impl! { usize = u64, 64,
|
2015-03-18 09:36:18 -07:00
|
|
|
intrinsics::ctpop64,
|
|
|
|
|
intrinsics::ctlz64,
|
|
|
|
|
intrinsics::cttz64,
|
|
|
|
|
intrinsics::bswap64,
|
|
|
|
|
intrinsics::u64_add_with_overflow,
|
|
|
|
|
intrinsics::u64_sub_with_overflow,
|
|
|
|
|
intrinsics::u64_mul_with_overflow }
|
2015-03-10 23:13:40 -05:00
|
|
|
}
|
|
|
|
|
|
2014-04-30 22:14:22 -07:00
|
|
|
/// A generic trait for converting a value to a number.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub trait ToPrimitive {
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Converts the value of `self` to an `isize`.
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "use to_isize")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_int(&self) -> Option<isize> {
|
2015-02-19 21:05:35 -08:00
|
|
|
self.to_i64().and_then(|x| x.to_isize())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `isize`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_isize(&self) -> Option<isize> {
|
|
|
|
|
self.to_i64().and_then(|x| x.to_isize())
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `i8`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i8(&self) -> Option<i8> {
|
|
|
|
|
self.to_i64().and_then(|x| x.to_i8())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `i16`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i16(&self) -> Option<i16> {
|
|
|
|
|
self.to_i64().and_then(|x| x.to_i16())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `i32`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i32(&self) -> Option<i32> {
|
|
|
|
|
self.to_i64().and_then(|x| x.to_i32())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `i64`.
|
|
|
|
|
fn to_i64(&self) -> Option<i64>;
|
|
|
|
|
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Converts the value of `self` to an `usize`.
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "use to_usize")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_uint(&self) -> Option<usize> {
|
2015-02-19 21:05:35 -08:00
|
|
|
self.to_u64().and_then(|x| x.to_usize())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to a `usize`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_usize(&self) -> Option<usize> {
|
|
|
|
|
self.to_u64().and_then(|x| x.to_usize())
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `u8`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u8(&self) -> Option<u8> {
|
|
|
|
|
self.to_u64().and_then(|x| x.to_u8())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `u16`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u16(&self) -> Option<u16> {
|
|
|
|
|
self.to_u64().and_then(|x| x.to_u16())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `u32`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u32(&self) -> Option<u32> {
|
|
|
|
|
self.to_u64().and_then(|x| x.to_u32())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `u64`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u64(&self) -> Option<u64>;
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `f32`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f32(&self) -> Option<f32> {
|
|
|
|
|
self.to_f64().and_then(|x| x.to_f32())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Converts the value of `self` to an `f64`.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f64(&self) -> Option<f64> {
|
|
|
|
|
self.to_i64().and_then(|x| x.to_f64())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_int_to_int {
|
2014-07-07 16:26:30 -07:00
|
|
|
($SrcT:ty, $DstT:ty, $slf:expr) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
{
|
|
|
|
|
if size_of::<$SrcT>() <= size_of::<$DstT>() {
|
2014-07-07 16:26:30 -07:00
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
2014-07-07 16:26:30 -07:00
|
|
|
let n = $slf as i64;
|
2014-11-10 01:20:13 +11:00
|
|
|
let min_value: $DstT = Int::min_value();
|
|
|
|
|
let max_value: $DstT = Int::max_value();
|
2014-04-30 22:14:22 -07:00
|
|
|
if min_value as i64 <= n && n <= max_value as i64 {
|
2014-07-07 16:26:30 -07:00
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_int_to_uint {
|
2014-07-07 16:26:30 -07:00
|
|
|
($SrcT:ty, $DstT:ty, $slf:expr) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
{
|
2014-11-10 09:35:53 +11:00
|
|
|
let zero: $SrcT = Int::zero();
|
2014-11-10 01:20:13 +11:00
|
|
|
let max_value: $DstT = Int::max_value();
|
2014-07-07 16:26:30 -07:00
|
|
|
if zero <= $slf && $slf as u64 <= max_value as u64 {
|
|
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_int {
|
2014-04-30 22:14:22 -07:00
|
|
|
($T:ty) => (
|
|
|
|
|
impl ToPrimitive for $T {
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_int(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
|
|
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_uint(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
|
|
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2015-02-19 21:05:35 -08:00
|
|
|
impl_to_primitive_int! { isize }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_to_primitive_int! { i8 }
|
|
|
|
|
impl_to_primitive_int! { i16 }
|
|
|
|
|
impl_to_primitive_int! { i32 }
|
|
|
|
|
impl_to_primitive_int! { i64 }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_uint_to_int {
|
2014-07-07 16:26:30 -07:00
|
|
|
($DstT:ty, $slf:expr) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
{
|
2014-11-10 01:20:13 +11:00
|
|
|
let max_value: $DstT = Int::max_value();
|
2014-07-07 16:26:30 -07:00
|
|
|
if $slf as u64 <= max_value as u64 {
|
|
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_uint_to_uint {
|
2014-07-07 16:26:30 -07:00
|
|
|
($SrcT:ty, $DstT:ty, $slf:expr) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
{
|
|
|
|
|
if size_of::<$SrcT>() <= size_of::<$DstT>() {
|
2014-07-07 16:26:30 -07:00
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
2014-11-10 09:35:53 +11:00
|
|
|
let zero: $SrcT = Int::zero();
|
2014-11-10 01:20:13 +11:00
|
|
|
let max_value: $DstT = Int::max_value();
|
2014-07-07 16:26:30 -07:00
|
|
|
if zero <= $slf && $slf as u64 <= max_value as u64 {
|
|
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_uint {
|
2014-04-30 22:14:22 -07:00
|
|
|
($T:ty) => (
|
|
|
|
|
impl ToPrimitive for $T {
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_int(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
|
2015-02-19 21:05:35 -08:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_uint(&self) -> Option<usize> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_usize(&self) -> Option<usize> {
|
|
|
|
|
impl_to_primitive_uint_to_uint!($T, usize, *self)
|
|
|
|
|
}
|
2015-02-19 21:05:35 -08:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2015-02-19 21:05:35 -08:00
|
|
|
impl_to_primitive_uint! { usize }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_to_primitive_uint! { u8 }
|
|
|
|
|
impl_to_primitive_uint! { u16 }
|
|
|
|
|
impl_to_primitive_uint! { u32 }
|
|
|
|
|
impl_to_primitive_uint! { u64 }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_float_to_float {
|
2015-01-05 18:30:55 +11:00
|
|
|
($SrcT:ident, $DstT:ident, $slf:expr) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
if size_of::<$SrcT>() <= size_of::<$DstT>() {
|
2014-07-07 16:26:30 -07:00
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
2014-07-07 16:26:30 -07:00
|
|
|
let n = $slf as f64;
|
2015-02-13 14:40:57 +11:00
|
|
|
let max_value: $SrcT = ::$SrcT::MAX;
|
2014-04-30 22:14:22 -07:00
|
|
|
if -max_value as f64 <= n && n <= max_value as f64 {
|
2014-07-07 16:26:30 -07:00
|
|
|
Some($slf as $DstT)
|
2014-04-30 22:14:22 -07:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_to_primitive_float {
|
2015-01-05 18:30:55 +11:00
|
|
|
($T:ident) => (
|
2014-04-30 22:14:22 -07:00
|
|
|
impl ToPrimitive for $T {
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_int(&self) -> Option<isize> { Some(*self as isize) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
|
2015-02-19 21:05:35 -08:00
|
|
|
#[inline]
|
2014-04-30 22:14:22 -07:00
|
|
|
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_uint(&self) -> Option<usize> { Some(*self as usize) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
|
2015-02-19 21:05:35 -08:00
|
|
|
#[inline]
|
2014-04-30 22:14:22 -07:00
|
|
|
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
#[inline]
|
2014-07-07 16:26:30 -07:00
|
|
|
fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_to_primitive_float! { f32 }
|
|
|
|
|
impl_to_primitive_float! { f64 }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
/// A generic trait for converting a number to a value.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
2015-01-07 11:33:42 +13:00
|
|
|
pub trait FromPrimitive : ::marker::Sized {
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Convert an `isize` to return an optional value of this type. If the
|
2014-04-30 22:14:22 -07:00
|
|
|
/// value cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "use from_isize")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn from_int(n: isize) -> Option<Self> {
|
2014-04-30 22:14:22 -07:00
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 21:05:35 -08:00
|
|
|
/// Convert an `isize` to return an optional value of this type. If the
|
|
|
|
|
/// value cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_isize(n: isize) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-30 22:14:22 -07:00
|
|
|
/// Convert an `i8` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_i8(n: i8) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `i16` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_i16(n: i16) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `i32` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_i32(n: i32) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `i64` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
fn from_i64(n: i64) -> Option<Self>;
|
|
|
|
|
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Convert an `usize` to return an optional value of this type. If the
|
2014-04-30 22:14:22 -07:00
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "use from_usize")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn from_uint(n: usize) -> Option<Self> {
|
2014-04-30 22:14:22 -07:00
|
|
|
FromPrimitive::from_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 21:05:35 -08:00
|
|
|
/// Convert a `usize` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_usize(n: usize) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-30 22:14:22 -07:00
|
|
|
/// Convert an `u8` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_u8(n: u8) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `u16` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_u16(n: u16) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `u32` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_u32(n: u32) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert an `u64` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
fn from_u64(n: u64) -> Option<Self>;
|
|
|
|
|
|
|
|
|
|
/// Convert a `f32` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_f32(n: f32) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_f64(n as f64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Convert a `f64` to return an optional value of this type. If the
|
|
|
|
|
/// type cannot be represented by this value, the `None` is returned.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from_f64(n: f64) -> Option<Self> {
|
|
|
|
|
FromPrimitive::from_i64(n as i64)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_int`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[deprecated(since = "1.0.0", reason = "use from_isize")]
|
2015-03-25 17:06:52 -07:00
|
|
|
pub fn from_int<A: FromPrimitive>(n: isize) -> Option<A> {
|
2015-02-19 21:05:35 -08:00
|
|
|
FromPrimitive::from_isize(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_isize`.
|
|
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
|
|
|
|
pub fn from_isize<A: FromPrimitive>(n: isize) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_isize(n)
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_i8`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_i8(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_i16`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_i16(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_i32`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_i32(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_i64`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_i64(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_uint`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2015-02-19 21:05:35 -08:00
|
|
|
#[deprecated(since = "1.0.0", reason = "use from_uint")]
|
2015-03-25 17:06:52 -07:00
|
|
|
pub fn from_uint<A: FromPrimitive>(n: usize) -> Option<A> {
|
2015-02-19 21:05:35 -08:00
|
|
|
FromPrimitive::from_usize(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_usize`.
|
|
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
|
|
|
|
pub fn from_usize<A: FromPrimitive>(n: usize) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_usize(n)
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_u8`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_u8(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_u16`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_u16(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_u32`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_u32(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_u64`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_u64(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_f32`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_f32(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A utility function that just calls `FromPrimitive::from_f64`.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
|
|
|
|
|
FromPrimitive::from_f64(n)
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_from_primitive {
|
2014-07-07 16:26:30 -07:00
|
|
|
($T:ty, $to_ty:ident) => (
|
Add #[allow_internal_unstable] to track stability for macros better.
Unstable items used in a macro expansion will now always trigger
stability warnings, *unless* the unstable items are directly inside a
macro marked with `#[allow_internal_unstable]`. IOW, the compiler warns
unless the span of the unstable item is a subspan of the definition of a
macro marked with that attribute.
E.g.
#[allow_internal_unstable]
macro_rules! foo {
($e: expr) => {{
$e;
unstable(); // no warning
only_called_by_foo!();
}}
}
macro_rules! only_called_by_foo {
() => { unstable() } // warning
}
foo!(unstable()) // warning
The unstable inside `foo` is fine, due to the attribute. But the
`unstable` inside `only_called_by_foo` is not, since that macro doesn't
have the attribute, and the `unstable` passed into `foo` is also not
fine since it isn't contained in the macro itself (that is, even though
it is only used directly in the macro).
In the process this makes the stability tracking much more precise,
e.g. previously `println!("{}", unstable())` got no warning, but now it
does. As such, this is a bug fix that may cause [breaking-change]s.
The attribute is definitely feature gated, since it explicitly allows
side-stepping the feature gating system.
2015-03-01 14:09:28 +11:00
|
|
|
#[allow(deprecated)]
|
2014-04-30 22:14:22 -07:00
|
|
|
impl FromPrimitive for $T {
|
2015-03-25 17:06:52 -07:00
|
|
|
#[inline] fn from_int(n: isize) -> Option<$T> { n.$to_ty() }
|
2014-07-07 16:26:30 -07:00
|
|
|
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
|
2015-03-25 17:06:52 -07:00
|
|
|
#[inline] fn from_uint(n: usize) -> Option<$T> { n.$to_ty() }
|
2014-07-07 16:26:30 -07:00
|
|
|
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
|
|
|
|
|
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
|
|
|
|
|
#[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
|
2014-04-30 22:14:22 -07:00
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
|
|
|
|
|
2015-03-25 17:06:52 -07:00
|
|
|
impl_from_primitive! { isize, to_int }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_from_primitive! { i8, to_i8 }
|
|
|
|
|
impl_from_primitive! { i16, to_i16 }
|
|
|
|
|
impl_from_primitive! { i32, to_i32 }
|
|
|
|
|
impl_from_primitive! { i64, to_i64 }
|
2015-03-25 17:06:52 -07:00
|
|
|
impl_from_primitive! { usize, to_uint }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_from_primitive! { u8, to_u8 }
|
|
|
|
|
impl_from_primitive! { u16, to_u16 }
|
|
|
|
|
impl_from_primitive! { u32, to_u32 }
|
|
|
|
|
impl_from_primitive! { u64, to_u64 }
|
|
|
|
|
impl_from_primitive! { f32, to_f32 }
|
|
|
|
|
impl_from_primitive! { f64, to_f64 }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
|
|
|
|
/// Cast from one machine scalar to another.
|
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-04-30 22:14:22 -07:00
|
|
|
///
|
|
|
|
|
/// ```
|
2015-03-13 15:28:35 -07:00
|
|
|
/// # #![feature(core)]
|
2014-04-30 22:14:22 -07:00
|
|
|
/// use std::num;
|
|
|
|
|
///
|
2015-01-22 14:08:56 +00:00
|
|
|
/// let twenty: f32 = num::cast(0x14).unwrap();
|
2014-04-30 22:14:22 -07:00
|
|
|
/// assert_eq!(twenty, 20f32);
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
#[inline]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
|
|
|
|
|
NumCast::from(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An interface for casting between machine scalars.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
2014-04-30 22:14:22 -07:00
|
|
|
pub trait NumCast: ToPrimitive {
|
|
|
|
|
/// Creates a number from another value that can be converted into a primitive via the
|
|
|
|
|
/// `ToPrimitive` trait.
|
|
|
|
|
fn from<T: ToPrimitive>(n: T) -> Option<Self>;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! impl_num_cast {
|
2014-04-30 22:14:22 -07:00
|
|
|
($T:ty, $conv:ident) => (
|
|
|
|
|
impl NumCast for $T {
|
|
|
|
|
#[inline]
|
Add #[allow_internal_unstable] to track stability for macros better.
Unstable items used in a macro expansion will now always trigger
stability warnings, *unless* the unstable items are directly inside a
macro marked with `#[allow_internal_unstable]`. IOW, the compiler warns
unless the span of the unstable item is a subspan of the definition of a
macro marked with that attribute.
E.g.
#[allow_internal_unstable]
macro_rules! foo {
($e: expr) => {{
$e;
unstable(); // no warning
only_called_by_foo!();
}}
}
macro_rules! only_called_by_foo {
() => { unstable() } // warning
}
foo!(unstable()) // warning
The unstable inside `foo` is fine, due to the attribute. But the
`unstable` inside `only_called_by_foo` is not, since that macro doesn't
have the attribute, and the `unstable` passed into `foo` is also not
fine since it isn't contained in the macro itself (that is, even though
it is only used directly in the macro).
In the process this makes the stability tracking much more precise,
e.g. previously `println!("{}", unstable())` got no warning, but now it
does. As such, this is a bug fix that may cause [breaking-change]s.
The attribute is definitely feature gated, since it explicitly allows
side-stepping the feature gating system.
2015-03-01 14:09:28 +11:00
|
|
|
#[allow(deprecated)]
|
2014-04-30 22:14:22 -07:00
|
|
|
fn from<N: ToPrimitive>(n: N) -> Option<$T> {
|
|
|
|
|
// `$conv` could be generated using `concat_idents!`, but that
|
|
|
|
|
// macro seems to be broken at the moment
|
|
|
|
|
n.$conv()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl_num_cast! { u8, to_u8 }
|
|
|
|
|
impl_num_cast! { u16, to_u16 }
|
|
|
|
|
impl_num_cast! { u32, to_u32 }
|
|
|
|
|
impl_num_cast! { u64, to_u64 }
|
2015-03-25 17:06:52 -07:00
|
|
|
impl_num_cast! { usize, to_uint }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_num_cast! { i8, to_i8 }
|
|
|
|
|
impl_num_cast! { i16, to_i16 }
|
|
|
|
|
impl_num_cast! { i32, to_i32 }
|
|
|
|
|
impl_num_cast! { i64, to_i64 }
|
2015-03-25 17:06:52 -07:00
|
|
|
impl_num_cast! { isize, to_int }
|
2014-11-14 09:18:10 -08:00
|
|
|
impl_num_cast! { f32, to_f32 }
|
|
|
|
|
impl_num_cast! { f64, to_f64 }
|
2014-04-30 22:14:22 -07:00
|
|
|
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Used for representing the classification of floating point numbers
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Copy, PartialEq, Debug)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "may be renamed")]
|
2014-12-22 22:50:57 +01:00
|
|
|
pub enum FpCategory {
|
2014-05-10 13:25:49 -07:00
|
|
|
/// "Not a Number", often obtained by dividing by zero
|
2014-12-22 22:50:57 +01:00
|
|
|
Nan,
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Positive or negative infinity
|
2014-12-22 22:50:57 +01:00
|
|
|
Infinite ,
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Positive or negative zero
|
2014-12-22 22:50:57 +01:00
|
|
|
Zero,
|
|
|
|
|
/// De-normalized floating point representation (less precise than `Normal`)
|
|
|
|
|
Subnormal,
|
2014-05-10 13:25:49 -07:00
|
|
|
/// A regular floating point number
|
2014-12-22 22:50:57 +01:00
|
|
|
Normal,
|
2014-05-10 13:25:49 -07:00
|
|
|
}
|
|
|
|
|
|
2014-11-10 16:00:13 +11:00
|
|
|
/// A built-in floating point number.
|
2014-05-10 13:25:49 -07:00
|
|
|
// FIXME(#5527): In a future version of Rust, many of these functions will
|
|
|
|
|
// become constants.
|
|
|
|
|
//
|
|
|
|
|
// FIXME(#8888): Several of these functions have a parameter named
|
|
|
|
|
// `unused_self`. Removing it requires #8888 to be fixed.
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "distribution of methods between core/std is unclear")]
|
2014-11-10 11:30:52 +11:00
|
|
|
pub trait Float
|
|
|
|
|
: Copy + Clone
|
|
|
|
|
+ NumCast
|
|
|
|
|
+ PartialOrd
|
|
|
|
|
+ PartialEq
|
2015-01-02 22:56:24 -05:00
|
|
|
+ Neg<Output=Self>
|
2014-12-31 15:45:13 -05:00
|
|
|
+ Add<Output=Self>
|
|
|
|
|
+ Sub<Output=Self>
|
|
|
|
|
+ Mul<Output=Self>
|
|
|
|
|
+ Div<Output=Self>
|
|
|
|
|
+ Rem<Output=Self>
|
2014-11-10 11:30:52 +11:00
|
|
|
{
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the NaN value.
|
|
|
|
|
fn nan() -> Self;
|
|
|
|
|
/// Returns the infinite value.
|
|
|
|
|
fn infinity() -> Self;
|
|
|
|
|
/// Returns the negative infinite value.
|
|
|
|
|
fn neg_infinity() -> Self;
|
2014-11-10 09:35:53 +11:00
|
|
|
/// Returns the `0` value.
|
|
|
|
|
fn zero() -> Self;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns -0.0.
|
|
|
|
|
fn neg_zero() -> Self;
|
2014-11-10 09:35:53 +11:00
|
|
|
/// Returns the `1` value.
|
|
|
|
|
fn one() -> Self;
|
2014-05-10 13:25:49 -07:00
|
|
|
|
|
|
|
|
// FIXME (#5527): These should be associated constants
|
|
|
|
|
|
|
|
|
|
/// Returns the number of binary digits of mantissa that this type supports.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::MANTISSA_DIGITS` or \
|
|
|
|
|
`std::f64::MANTISSA_DIGITS` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn mantissa_digits(unused_self: Option<Self>) -> usize;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the number of base-10 digits of precision that this type supports.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn digits(unused_self: Option<Self>) -> usize;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")]
|
2014-05-10 13:25:49 -07:00
|
|
|
fn epsilon() -> Self;
|
|
|
|
|
/// Returns the minimum binary exponent that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn min_exp(unused_self: Option<Self>) -> isize;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the maximum binary exponent that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn max_exp(unused_self: Option<Self>) -> isize;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the minimum base-10 exponent that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn min_10_exp(unused_self: Option<Self>) -> isize;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the maximum base-10 exponent that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
|
2015-03-25 17:06:52 -07:00
|
|
|
fn max_10_exp(unused_self: Option<Self>) -> isize;
|
2014-11-10 01:20:13 +11:00
|
|
|
/// Returns the smallest finite value that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-02-13 14:40:57 +11:00
|
|
|
reason = "use `std::f32::MIN` or `std::f64::MIN` as appropriate")]
|
2014-11-10 01:20:13 +11:00
|
|
|
fn min_value() -> Self;
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the smallest normalized positive number that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-02-13 14:40:57 +11:00
|
|
|
reason = "use `std::f32::MIN_POSITIVE` or \
|
|
|
|
|
`std::f64::MIN_POSITIVE` as appropriate")]
|
2014-05-10 13:25:49 -07:00
|
|
|
fn min_pos_value(unused_self: Option<Self>) -> Self;
|
2014-11-10 01:20:13 +11:00
|
|
|
/// Returns the largest finite value that this type can represent.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-02-13 14:40:57 +11:00
|
|
|
reason = "use `std::f32::MAX` or `std::f64::MAX` as appropriate")]
|
2014-11-10 01:20:13 +11:00
|
|
|
fn max_value() -> Self;
|
2014-05-10 13:25:49 -07:00
|
|
|
|
2015-01-02 22:33:07 +11:00
|
|
|
/// Returns true if this value is NaN and false otherwise.
|
|
|
|
|
fn is_nan(self) -> bool;
|
|
|
|
|
/// Returns true if this value is positive infinity or negative infinity and
|
|
|
|
|
/// false otherwise.
|
|
|
|
|
fn is_infinite(self) -> bool;
|
|
|
|
|
/// Returns true if this number is neither infinite nor NaN.
|
|
|
|
|
fn is_finite(self) -> bool;
|
|
|
|
|
/// Returns true if this number is neither zero, infinite, denormal, or NaN.
|
|
|
|
|
fn is_normal(self) -> bool;
|
|
|
|
|
/// Returns the category that this number falls into.
|
|
|
|
|
fn classify(self) -> FpCategory;
|
|
|
|
|
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Returns the mantissa, exponent and sign as integers, respectively.
|
|
|
|
|
fn integer_decode(self) -> (u64, i16, i8);
|
|
|
|
|
|
|
|
|
|
/// Return the largest integer less than or equal to a number.
|
|
|
|
|
fn floor(self) -> Self;
|
|
|
|
|
/// Return the smallest integer greater than or equal to a number.
|
|
|
|
|
fn ceil(self) -> Self;
|
|
|
|
|
/// Return the nearest integer to a number. Round half-way cases away from
|
|
|
|
|
/// `0.0`.
|
|
|
|
|
fn round(self) -> Self;
|
|
|
|
|
/// Return the integer part of a number.
|
|
|
|
|
fn trunc(self) -> Self;
|
|
|
|
|
/// Return the fractional part of a number.
|
|
|
|
|
fn fract(self) -> Self;
|
|
|
|
|
|
2014-11-13 00:02:42 +11:00
|
|
|
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
|
|
|
|
|
/// number is `Float::nan()`.
|
|
|
|
|
fn abs(self) -> Self;
|
|
|
|
|
/// Returns a number that represents the sign of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
|
|
|
|
|
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
|
|
|
|
|
/// - `Float::nan()` if the number is `Float::nan()`
|
|
|
|
|
fn signum(self) -> Self;
|
|
|
|
|
/// Returns `true` if `self` is positive, including `+0.0` and
|
|
|
|
|
/// `Float::infinity()`.
|
|
|
|
|
fn is_positive(self) -> bool;
|
|
|
|
|
/// Returns `true` if `self` is negative, including `-0.0` and
|
|
|
|
|
/// `Float::neg_infinity()`.
|
|
|
|
|
fn is_negative(self) -> bool;
|
|
|
|
|
|
2014-05-10 13:25:49 -07:00
|
|
|
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
|
|
|
|
|
/// error. This produces a more accurate result with better performance than
|
|
|
|
|
/// a separate multiplication operation followed by an add.
|
|
|
|
|
fn mul_add(self, a: Self, b: Self) -> Self;
|
|
|
|
|
/// Take the reciprocal (inverse) of a number, `1/x`.
|
|
|
|
|
fn recip(self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Raise a number to an integer power.
|
|
|
|
|
///
|
|
|
|
|
/// Using this function is generally faster than using `powf`
|
|
|
|
|
fn powi(self, n: i32) -> Self;
|
|
|
|
|
/// Raise a number to a floating point power.
|
|
|
|
|
fn powf(self, n: Self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Take the square root of a number.
|
2014-10-20 11:39:01 +11:00
|
|
|
///
|
2014-10-28 15:07:22 +01:00
|
|
|
/// Returns NaN if `self` is a negative number.
|
2014-05-10 13:25:49 -07:00
|
|
|
fn sqrt(self) -> Self;
|
|
|
|
|
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
|
|
|
|
fn rsqrt(self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Returns `e^(self)`, (the exponential function).
|
|
|
|
|
fn exp(self) -> Self;
|
|
|
|
|
/// Returns 2 raised to the power of the number, `2^(self)`.
|
|
|
|
|
fn exp2(self) -> Self;
|
|
|
|
|
/// Returns the natural logarithm of the number.
|
|
|
|
|
fn ln(self) -> Self;
|
|
|
|
|
/// Returns the logarithm of the number with respect to an arbitrary base.
|
|
|
|
|
fn log(self, base: Self) -> Self;
|
|
|
|
|
/// Returns the base 2 logarithm of the number.
|
|
|
|
|
fn log2(self) -> Self;
|
|
|
|
|
/// Returns the base 10 logarithm of the number.
|
|
|
|
|
fn log10(self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Convert radians to degrees.
|
|
|
|
|
fn to_degrees(self) -> Self;
|
|
|
|
|
/// Convert degrees to radians.
|
|
|
|
|
fn to_radians(self) -> Self;
|
|
|
|
|
}
|
2014-11-09 16:59:28 +11:00
|
|
|
|
2014-11-15 15:52:00 +11:00
|
|
|
/// A generic trait for converting a string with a radix (base) to a value
|
2015-01-27 22:52:32 -08:00
|
|
|
#[unstable(feature = "core", reason = "needs reevaluation")]
|
2014-11-15 15:52:00 +11:00
|
|
|
pub trait FromStrRadix {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err;
|
2015-02-15 00:10:19 +03:00
|
|
|
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::Err>;
|
2014-11-15 15:52:00 +11:00
|
|
|
}
|
|
|
|
|
|
2015-03-07 18:03:38 +08:00
|
|
|
/// A utility function that just calls `FromStrRadix::from_str_radix`.
|
2015-01-27 22:52:32 -08:00
|
|
|
#[unstable(feature = "core", reason = "needs reevaluation")]
|
2015-02-15 00:10:19 +03:00
|
|
|
pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: u32)
|
2015-01-27 22:52:32 -08:00
|
|
|
-> Result<T, T::Err> {
|
2014-11-15 15:52:00 +11:00
|
|
|
FromStrRadix::from_str_radix(str, radix)
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-15 17:02:38 +11:00
|
|
|
macro_rules! from_str_radix_float_impl {
|
|
|
|
|
($T:ty) => {
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 17:02:38 +11:00
|
|
|
impl FromStr for $T {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err = ParseFloatError;
|
|
|
|
|
|
2014-11-15 17:02:38 +11:00
|
|
|
/// Convert a string in base 10 to a float.
|
|
|
|
|
/// Accepts an optional decimal exponent.
|
|
|
|
|
///
|
|
|
|
|
/// This function accepts strings such as
|
|
|
|
|
///
|
|
|
|
|
/// * '3.14'
|
|
|
|
|
/// * '+3.14', equivalent to '3.14'
|
|
|
|
|
/// * '-3.14'
|
|
|
|
|
/// * '2.5E10', or equivalently, '2.5e10'
|
|
|
|
|
/// * '2.5E-10'
|
|
|
|
|
/// * '.' (understood as 0)
|
|
|
|
|
/// * '5.'
|
|
|
|
|
/// * '.5', or, equivalently, '0.5'
|
|
|
|
|
/// * '+inf', 'inf', '-inf', 'NaN'
|
|
|
|
|
///
|
|
|
|
|
/// Leading and trailing whitespace represent an error.
|
|
|
|
|
///
|
|
|
|
|
/// # Arguments
|
|
|
|
|
///
|
|
|
|
|
/// * src - A string
|
|
|
|
|
///
|
|
|
|
|
/// # Return value
|
|
|
|
|
///
|
|
|
|
|
/// `None` if the string did not represent a valid number. Otherwise,
|
|
|
|
|
/// `Some(n)` where `n` is the floating-point number represented by `src`.
|
|
|
|
|
#[inline]
|
2015-01-27 22:52:32 -08:00
|
|
|
fn from_str(src: &str) -> Result<$T, ParseFloatError> {
|
2014-11-15 17:02:38 +11:00
|
|
|
from_str_radix(src, 10)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 17:02:38 +11:00
|
|
|
impl FromStrRadix for $T {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err = ParseFloatError;
|
|
|
|
|
|
2014-11-15 17:02:38 +11:00
|
|
|
/// Convert a string in a given base to a float.
|
|
|
|
|
///
|
|
|
|
|
/// Due to possible conflicts, this function does **not** accept
|
|
|
|
|
/// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
|
|
|
|
|
/// does it recognize exponents of any kind.
|
|
|
|
|
///
|
|
|
|
|
/// Leading and trailing whitespace represent an error.
|
|
|
|
|
///
|
|
|
|
|
/// # Arguments
|
|
|
|
|
///
|
|
|
|
|
/// * src - A string
|
|
|
|
|
/// * radix - The base to use. Must lie in the range [2 .. 36]
|
|
|
|
|
///
|
|
|
|
|
/// # Return value
|
|
|
|
|
///
|
2015-01-27 22:52:32 -08:00
|
|
|
/// `None` if the string did not represent a valid number.
|
|
|
|
|
/// Otherwise, `Some(n)` where `n` is the floating-point number
|
|
|
|
|
/// represented by `src`.
|
2015-02-15 00:10:19 +03:00
|
|
|
fn from_str_radix(src: &str, radix: u32)
|
2015-01-27 22:52:32 -08:00
|
|
|
-> Result<$T, ParseFloatError> {
|
|
|
|
|
use self::FloatErrorKind::*;
|
|
|
|
|
use self::ParseFloatError as PFE;
|
|
|
|
|
assert!(radix >= 2 && radix <= 36,
|
2014-11-15 17:02:38 +11:00
|
|
|
"from_str_radix_float: must lie in the range `[2, 36]` - found {}",
|
|
|
|
|
radix);
|
|
|
|
|
|
|
|
|
|
// Special values
|
|
|
|
|
match src {
|
2015-01-27 22:52:32 -08:00
|
|
|
"inf" => return Ok(Float::infinity()),
|
|
|
|
|
"-inf" => return Ok(Float::neg_infinity()),
|
|
|
|
|
"NaN" => return Ok(Float::nan()),
|
2014-11-15 17:02:38 +11:00
|
|
|
_ => {},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let (is_positive, src) = match src.slice_shift_char() {
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PFE { kind: Empty }),
|
|
|
|
|
Some(('-', "")) => return Err(PFE { kind: Empty }),
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
Some(('-', src)) => (false, src),
|
|
|
|
|
Some((_, _)) => (true, src),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// The significand to accumulate
|
|
|
|
|
let mut sig = if is_positive { 0.0 } else { -0.0 };
|
|
|
|
|
// Necessary to detect overflow
|
|
|
|
|
let mut prev_sig = sig;
|
|
|
|
|
let mut cs = src.chars().enumerate();
|
|
|
|
|
// Exponent prefix and exponent index offset
|
2015-03-25 17:06:52 -07:00
|
|
|
let mut exp_info = None::<(char, usize)>;
|
2014-11-15 17:02:38 +11:00
|
|
|
|
|
|
|
|
// Parse the integer part of the significand
|
2015-01-10 21:50:07 -05:00
|
|
|
for (i, c) in cs.by_ref() {
|
2014-11-15 17:02:38 +11:00
|
|
|
match c.to_digit(radix) {
|
|
|
|
|
Some(digit) => {
|
|
|
|
|
// shift significand one digit left
|
|
|
|
|
sig = sig * (radix as $T);
|
|
|
|
|
|
|
|
|
|
// add/subtract current digit depending on sign
|
|
|
|
|
if is_positive {
|
2015-03-25 17:06:52 -07:00
|
|
|
sig = sig + ((digit as isize) as $T);
|
2014-11-15 17:02:38 +11:00
|
|
|
} else {
|
2015-03-25 17:06:52 -07:00
|
|
|
sig = sig - ((digit as isize) as $T);
|
2014-11-15 17:02:38 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Detect overflow by comparing to last value, except
|
|
|
|
|
// if we've not seen any non-zero digits.
|
|
|
|
|
if prev_sig != 0.0 {
|
|
|
|
|
if is_positive && sig <= prev_sig
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
if !is_positive && sig >= prev_sig
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::neg_infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
|
|
|
|
|
// Detect overflow by reversing the shift-and-add process
|
|
|
|
|
if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::neg_infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
}
|
|
|
|
|
prev_sig = sig;
|
|
|
|
|
},
|
|
|
|
|
None => match c {
|
|
|
|
|
'e' | 'E' | 'p' | 'P' => {
|
|
|
|
|
exp_info = Some((c, i + 1));
|
|
|
|
|
break; // start of exponent
|
|
|
|
|
},
|
|
|
|
|
'.' => {
|
|
|
|
|
break; // start of fractional part
|
|
|
|
|
},
|
|
|
|
|
_ => {
|
2015-01-27 22:52:32 -08:00
|
|
|
return Err(PFE { kind: Invalid });
|
2014-11-15 17:02:38 +11:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we are not yet at the exponent parse the fractional
|
|
|
|
|
// part of the significand
|
|
|
|
|
if exp_info.is_none() {
|
|
|
|
|
let mut power = 1.0;
|
2015-01-10 21:50:07 -05:00
|
|
|
for (i, c) in cs.by_ref() {
|
2014-11-15 17:02:38 +11:00
|
|
|
match c.to_digit(radix) {
|
|
|
|
|
Some(digit) => {
|
|
|
|
|
// Decrease power one order of magnitude
|
|
|
|
|
power = power / (radix as $T);
|
|
|
|
|
// add/subtract current digit depending on sign
|
|
|
|
|
sig = if is_positive {
|
|
|
|
|
sig + (digit as $T) * power
|
|
|
|
|
} else {
|
|
|
|
|
sig - (digit as $T) * power
|
|
|
|
|
};
|
|
|
|
|
// Detect overflow by comparing to last value
|
|
|
|
|
if is_positive && sig < prev_sig
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
if !is_positive && sig > prev_sig
|
2015-01-27 22:52:32 -08:00
|
|
|
{ return Ok(Float::neg_infinity()); }
|
2014-11-15 17:02:38 +11:00
|
|
|
prev_sig = sig;
|
|
|
|
|
},
|
|
|
|
|
None => match c {
|
|
|
|
|
'e' | 'E' | 'p' | 'P' => {
|
|
|
|
|
exp_info = Some((c, i + 1));
|
|
|
|
|
break; // start of exponent
|
|
|
|
|
},
|
|
|
|
|
_ => {
|
2015-01-27 22:52:32 -08:00
|
|
|
return Err(PFE { kind: Invalid });
|
2014-11-15 17:02:38 +11:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse and calculate the exponent
|
|
|
|
|
let exp = match exp_info {
|
|
|
|
|
Some((c, offset)) => {
|
|
|
|
|
let base = match c {
|
2015-01-22 14:08:56 +00:00
|
|
|
'E' | 'e' if radix == 10 => 10.0,
|
|
|
|
|
'P' | 'p' if radix == 16 => 2.0,
|
2015-01-27 22:52:32 -08:00
|
|
|
_ => return Err(PFE { kind: Invalid }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Parse the exponent as decimal integer
|
2015-01-07 11:58:31 -05:00
|
|
|
let src = &src[offset..];
|
2014-11-15 17:02:38 +11:00
|
|
|
let (is_positive, exp) = match src.slice_shift_char() {
|
2015-03-25 17:06:52 -07:00
|
|
|
Some(('-', src)) => (false, src.parse::<usize>()),
|
|
|
|
|
Some(('+', src)) => (true, src.parse::<usize>()),
|
|
|
|
|
Some((_, _)) => (true, src.parse::<usize>()),
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PFE { kind: Invalid }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
match (is_positive, exp) {
|
2015-01-27 22:52:32 -08:00
|
|
|
(true, Ok(exp)) => base.powi(exp as i32),
|
|
|
|
|
(false, Ok(exp)) => 1.0 / base.powi(exp as i32),
|
|
|
|
|
(_, Err(_)) => return Err(PFE { kind: Invalid }),
|
2014-11-15 17:02:38 +11:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
None => 1.0, // no exponent
|
|
|
|
|
};
|
|
|
|
|
|
2015-01-27 22:52:32 -08:00
|
|
|
Ok(sig * exp)
|
2014-11-15 17:02:38 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-14 09:18:10 -08:00
|
|
|
from_str_radix_float_impl! { f32 }
|
|
|
|
|
from_str_radix_float_impl! { f64 }
|
2014-11-15 17:02:38 +11:00
|
|
|
|
|
|
|
|
macro_rules! from_str_radix_int_impl {
|
|
|
|
|
($T:ty) => {
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 17:02:38 +11:00
|
|
|
impl FromStr for $T {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err = ParseIntError;
|
2014-11-15 17:02:38 +11:00
|
|
|
#[inline]
|
2015-01-27 22:52:32 -08:00
|
|
|
fn from_str(src: &str) -> Result<$T, ParseIntError> {
|
2014-11-15 17:02:38 +11:00
|
|
|
from_str_radix(src, 10)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 17:02:38 +11:00
|
|
|
impl FromStrRadix for $T {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err = ParseIntError;
|
2015-02-15 00:10:19 +03:00
|
|
|
fn from_str_radix(src: &str, radix: u32)
|
2015-01-27 22:52:32 -08:00
|
|
|
-> Result<$T, ParseIntError> {
|
|
|
|
|
use self::IntErrorKind::*;
|
|
|
|
|
use self::ParseIntError as PIE;
|
2014-11-15 17:02:38 +11:00
|
|
|
assert!(radix >= 2 && radix <= 36,
|
|
|
|
|
"from_str_radix_int: must lie in the range `[2, 36]` - found {}",
|
|
|
|
|
radix);
|
|
|
|
|
|
|
|
|
|
let is_signed_ty = (0 as $T) > Int::min_value();
|
|
|
|
|
|
|
|
|
|
match src.slice_shift_char() {
|
2015-02-24 02:40:32 +01:00
|
|
|
Some(('-', "")) => Err(PIE { kind: Empty }),
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
Some(('-', src)) if is_signed_ty => {
|
2014-11-15 17:02:38 +11:00
|
|
|
// The number is negative
|
|
|
|
|
let mut result = 0;
|
|
|
|
|
for c in src.chars() {
|
|
|
|
|
let x = match c.to_digit(radix) {
|
|
|
|
|
Some(x) => x,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: InvalidDigit }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
result = match result.checked_mul(radix as $T) {
|
|
|
|
|
Some(result) => result,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: Underflow }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
result = match result.checked_sub(x as $T) {
|
|
|
|
|
Some(result) => result,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: Underflow }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
}
|
2015-01-27 22:52:32 -08:00
|
|
|
Ok(result)
|
2014-11-15 17:02:38 +11:00
|
|
|
},
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
Some((_, _)) => {
|
2014-11-15 17:02:38 +11:00
|
|
|
// The number is signed
|
|
|
|
|
let mut result = 0;
|
|
|
|
|
for c in src.chars() {
|
|
|
|
|
let x = match c.to_digit(radix) {
|
|
|
|
|
Some(x) => x,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: InvalidDigit }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
result = match result.checked_mul(radix as $T) {
|
|
|
|
|
Some(result) => result,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: Overflow }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
result = match result.checked_add(x as $T) {
|
|
|
|
|
Some(result) => result,
|
2015-01-27 22:52:32 -08:00
|
|
|
None => return Err(PIE { kind: Overflow }),
|
2014-11-15 17:02:38 +11:00
|
|
|
};
|
|
|
|
|
}
|
2015-01-27 22:52:32 -08:00
|
|
|
Ok(result)
|
2014-11-15 17:02:38 +11:00
|
|
|
},
|
2015-01-27 22:52:32 -08:00
|
|
|
None => Err(ParseIntError { kind: Empty }),
|
2014-11-15 17:02:38 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-02-19 21:05:35 -08:00
|
|
|
from_str_radix_int_impl! { isize }
|
2014-11-14 09:18:10 -08:00
|
|
|
from_str_radix_int_impl! { i8 }
|
|
|
|
|
from_str_radix_int_impl! { i16 }
|
|
|
|
|
from_str_radix_int_impl! { i32 }
|
|
|
|
|
from_str_radix_int_impl! { i64 }
|
2015-02-19 21:05:35 -08:00
|
|
|
from_str_radix_int_impl! { usize }
|
2014-11-14 09:18:10 -08:00
|
|
|
from_str_radix_int_impl! { u8 }
|
|
|
|
|
from_str_radix_int_impl! { u16 }
|
|
|
|
|
from_str_radix_int_impl! { u32 }
|
|
|
|
|
from_str_radix_int_impl! { u64 }
|
2015-01-27 22:52:32 -08:00
|
|
|
|
|
|
|
|
/// An error which can be returned when parsing an integer.
|
2015-01-30 12:26:44 -08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub struct ParseIntError { kind: IntErrorKind }
|
|
|
|
|
|
2015-01-30 12:26:44 -08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2015-01-27 22:52:32 -08:00
|
|
|
enum IntErrorKind {
|
|
|
|
|
Empty,
|
|
|
|
|
InvalidDigit,
|
|
|
|
|
Overflow,
|
|
|
|
|
Underflow,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl fmt::Display for ParseIntError {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
self.description().fmt(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl Error for ParseIntError {
|
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
|
match self.kind {
|
|
|
|
|
IntErrorKind::Empty => "cannot parse integer from empty string",
|
|
|
|
|
IntErrorKind::InvalidDigit => "invalid digit found in string",
|
|
|
|
|
IntErrorKind::Overflow => "number too large to fit in target type",
|
|
|
|
|
IntErrorKind::Underflow => "number too small to fit in target type",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An error which can be returned when parsing a float.
|
2015-01-30 12:26:44 -08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub struct ParseFloatError { kind: FloatErrorKind }
|
|
|
|
|
|
2015-01-30 12:26:44 -08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2015-01-27 22:52:32 -08:00
|
|
|
enum FloatErrorKind {
|
|
|
|
|
Empty,
|
|
|
|
|
Invalid,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl fmt::Display for ParseFloatError {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
self.description().fmt(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl Error for ParseFloatError {
|
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
|
match self.kind {
|
|
|
|
|
FloatErrorKind::Empty => "cannot parse float from empty string",
|
|
|
|
|
FloatErrorKind::Invalid => "invalid float literal",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|