2019-01-20 00:59:58 -05:00
|
|
|
use crate::number::Number;
|
|
|
|
use crate::one::One;
|
|
|
|
use crate::zero::Zero;
|
2015-10-04 02:59:26 -04:00
|
|
|
|
|
|
|
|
|
|
|
/// A trait that defines what is required to be considered
|
|
|
|
/// an Integer. [List of types of numbers][1]
|
|
|
|
///
|
2015-12-01 15:48:02 -05:00
|
|
|
/// This is meant to have all the similarities between
|
|
|
|
/// [u8][2], [u16][3], [u32][4], [u64][5], [usize][6],
|
|
|
|
/// [i8][7], [i16][8], [i32][9], [i64][10], [isize][11].
|
|
|
|
/// Most of the comments and documentation were taken
|
|
|
|
/// from the [rust-lang std docs][12].
|
|
|
|
///
|
2015-10-04 02:59:26 -04:00
|
|
|
/// [1]: https://en.wikipedia.org/wiki/List_of_types_of_numbers
|
2015-12-01 15:48:02 -05:00
|
|
|
/// [2]: https://doc.rust-lang.org/std/primitive.u8.html
|
|
|
|
/// [3]: https://doc.rust-lang.org/std/primitive.u16.html
|
|
|
|
/// [4]: https://doc.rust-lang.org/std/primitive.u32.html
|
|
|
|
/// [5]: https://doc.rust-lang.org/std/primitive.u64.html
|
|
|
|
/// [6]: https://doc.rust-lang.org/std/primitive.usize.html
|
|
|
|
/// [7]: https://doc.rust-lang.org/std/primitive.i8.html
|
|
|
|
/// [8]: https://doc.rust-lang.org/std/primitive.i16.html
|
|
|
|
/// [9]: https://doc.rust-lang.org/std/primitive.i32.html
|
|
|
|
/// [10]: https://doc.rust-lang.org/std/primitive.i64.html
|
|
|
|
/// [11]: https://doc.rust-lang.org/std/primitive.isize.html
|
|
|
|
/// [12]: https://doc.rust-lang.org/std/index.html
|
2016-01-06 05:59:38 -05:00
|
|
|
pub trait Integer: Number
|
2015-10-04 02:59:26 -04:00
|
|
|
{
|
2017-07-01 15:32:44 -04:00
|
|
|
/// Computes the absolute value of `self`.
|
|
|
|
/// Returns ::MIN if the number is ::MIN.
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use sigils::{Integer, Number};
|
|
|
|
///
|
|
|
|
/// let x = -75i32;
|
|
|
|
/// let y = 84i16;
|
|
|
|
///
|
|
|
|
/// assert_eq!(x.abs(), 75i32);
|
|
|
|
/// assert_eq!(y.abs(), 84i16);
|
|
|
|
/// assert_eq!(u8::MIN.abs(), u8::MIN);
|
|
|
|
/// ```
|
|
|
|
fn abs(self) -> Self;
|
|
|
|
|
|
|
|
/// Returns a number that represents the sign of `self`.
|
|
|
|
///
|
|
|
|
/// - `1` if the number is positive, `(0, MAX]`
|
|
|
|
/// - `0` if the number is zero, `[0]`
|
|
|
|
/// - `-1` if the number is negative, `[MIN, 0)`
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use sigils::Integer;
|
|
|
|
///
|
|
|
|
/// let e = -3i32;
|
|
|
|
/// let f = 3u64;
|
|
|
|
/// let g = 0i64;
|
|
|
|
///
|
|
|
|
/// assert_eq!(e.signum(), -1i32);
|
|
|
|
/// assert_eq!(f.signum(), 1u64);
|
|
|
|
/// assert_eq!(g.signum(), 0i64);
|
|
|
|
/// ```
|
|
|
|
fn signum(self) -> Self;
|
|
|
|
|
|
|
|
/// Returns `true` if `self` is positive and
|
|
|
|
/// 'false' if the Integer is zero or negative.
|
|
|
|
/// (0, MAX]
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use sigils::Integer;
|
|
|
|
///
|
|
|
|
/// let e: i32;
|
|
|
|
/// let f: i32;
|
|
|
|
/// let g: u64;
|
|
|
|
///
|
|
|
|
/// e = 5i32;
|
|
|
|
/// f = -33i32;
|
|
|
|
/// g = 782u64;
|
|
|
|
///
|
|
|
|
/// assert!(e.is_sign_positive() == true);
|
|
|
|
/// assert!(f.is_sign_positive() == false);
|
|
|
|
/// assert!(g.is_sign_positive() == true);
|
|
|
|
/// ```
|
|
|
|
fn is_sign_positive(self) -> bool;
|
|
|
|
|
|
|
|
/// Returns `true` if `self` is negative and
|
|
|
|
/// 'false' if the Integer is zero or positive.
|
|
|
|
/// [MIN, 0)
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use sigils::Integer;
|
|
|
|
///
|
|
|
|
/// let e: i32;
|
|
|
|
/// let f: i32;
|
|
|
|
/// let g: u64;
|
|
|
|
///
|
|
|
|
/// e = 5i32;
|
|
|
|
/// f = -33i32;
|
|
|
|
/// g = 782u64;
|
|
|
|
///
|
|
|
|
/// assert!(e.is_sign_negative() == false);
|
|
|
|
/// assert!(f.is_sign_negative() == true);
|
|
|
|
/// assert!(g.is_sign_negative() == false);
|
|
|
|
/// ```
|
|
|
|
fn is_sign_negative(self) -> bool;
|
2015-10-04 02:59:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-01 15:32:44 -04:00
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
// Create a macro to ease typing and reading.
|
|
|
|
/// A macro to make implementing the trait easier for all the
|
2017-07-01 15:32:44 -04:00
|
|
|
/// base integer signed types in rust.
|
|
|
|
macro_rules! signed_trait_impl
|
2015-10-04 02:59:26 -04:00
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
2017-07-01 15:32:44 -04:00
|
|
|
fn abs(self) -> Self
|
|
|
|
{
|
|
|
|
if self < Self::zero()
|
|
|
|
{
|
|
|
|
-self
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn signum(self) -> Self
|
|
|
|
{
|
|
|
|
if self.is_sign_negative() == true
|
|
|
|
{
|
|
|
|
-1
|
|
|
|
}
|
|
|
|
else if self.is_sign_positive() == true
|
|
|
|
{
|
|
|
|
Self::one()
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Self::zero()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_sign_negative(self) -> bool
|
|
|
|
{
|
|
|
|
self < Self::zero()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_sign_positive(self) -> bool
|
|
|
|
{
|
|
|
|
self > Self::zero()
|
|
|
|
}
|
2015-10-04 02:59:26 -04:00
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
2017-07-01 15:32:44 -04:00
|
|
|
/// A macro to make implementing the trait easier for all the
|
|
|
|
/// base integer unsigned types in rust.
|
|
|
|
macro_rules! unsigned_trait_impl
|
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
fn abs(self) -> Self
|
|
|
|
{
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
fn signum(self) -> Self
|
|
|
|
{
|
|
|
|
if self == Self::zero()
|
|
|
|
{
|
|
|
|
Self::zero()
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Self::one()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_sign_negative(self) -> bool
|
|
|
|
{
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_sign_positive(self) -> bool
|
|
|
|
{
|
|
|
|
self > Self::zero()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
|
|
|
|
// Implement the trait for the types that are Integers.
|
2017-07-01 15:32:44 -04:00
|
|
|
signed_trait_impl!(Integer for i8 i16 i32 i64 isize);
|
|
|
|
unsigned_trait_impl!(Integer for u8 u16 u32 u64 usize);
|