Skip to content

Commit

Permalink
Introduce ToInt type operator
Browse files Browse the repository at this point in the history
The ToInt type operator return arbitrary integer types,
including {i,u}{8,16,32,64} types.
  • Loading branch information
jerry73204 committed Jul 24, 2020
1 parent 3589cd4 commit 466df16
Show file tree
Hide file tree
Showing 3 changed files with 422 additions and 44 deletions.
153 changes: 152 additions & 1 deletion src/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use consts::{N1, P1, U0, U1};
use private::{Internal, InternalMarker};
use private::{PrivateDivInt, PrivateIntegerAdd, PrivateRem};
use uint::{UInt, Unsigned};
use {Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo};
use {Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt};

pub use marker_traits::Integer;

Expand Down Expand Up @@ -1177,14 +1177,165 @@ where
}
}

// -----------------------------------------
// ToInt

impl ToInt<i8> for Z0 {
fn to_int() -> i8 {
Self::I8
}
}

impl ToInt<i16> for Z0 {
fn to_int() -> i16 {
Self::I16
}
}

impl ToInt<i32> for Z0 {
fn to_int() -> i32 {
Self::I32
}
}

impl ToInt<i64> for Z0 {
fn to_int() -> i64 {
Self::I64
}
}

// negative numbers

impl<U> ToInt<i8> for NInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i8 {
Self::I8
}
}

impl<U> ToInt<i16> for NInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i16 {
Self::I16
}
}

impl<U> ToInt<i32> for NInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i32 {
Self::I32
}
}

impl<U> ToInt<i64> for NInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i64 {
Self::I64
}
}

// positive numbers

impl<U> ToInt<i8> for PInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i8 {
Self::I8
}
}

impl<U> ToInt<i16> for PInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i16 {
Self::I16
}
}

impl<U> ToInt<i32> for PInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i32 {
Self::I32
}
}

impl<U> ToInt<i64> for PInt<U>
where
U: Unsigned + NonZero,
{
fn to_int() -> i64 {
Self::I64
}
}

#[cfg(test)]
mod tests {
use consts::*;
use type_operators::ToInt;
use Integer;

#[test]
fn to_ix_min() {
assert_eq!(N128::to_i8(), ::core::i8::MIN);
assert_eq!(N32768::to_i16(), ::core::i16::MIN);
}

#[test]
fn int_toint_test() {
// i8
assert_eq!(0_i8, Z0::to_int());
assert_eq!(1_i8, P1::to_int());
assert_eq!(2_i8, P2::to_int());
assert_eq!(3_i8, P3::to_int());
assert_eq!(4_i8, P4::to_int());
assert_eq!(-1_i8, N1::to_int());
assert_eq!(-2_i8, N2::to_int());
assert_eq!(-3_i8, N3::to_int());
assert_eq!(-4_i8, N4::to_int());

// i16
assert_eq!(0_i16, Z0::to_int());
assert_eq!(1_i16, P1::to_int());
assert_eq!(2_i16, P2::to_int());
assert_eq!(3_i16, P3::to_int());
assert_eq!(4_i16, P4::to_int());
assert_eq!(-1_i16, N1::to_int());
assert_eq!(-2_i16, N2::to_int());
assert_eq!(-3_i16, N3::to_int());
assert_eq!(-4_i16, N4::to_int());

// i32
assert_eq!(0_i32, Z0::to_int());
assert_eq!(1_i32, P1::to_int());
assert_eq!(2_i32, P2::to_int());
assert_eq!(3_i32, P3::to_int());
assert_eq!(4_i32, P4::to_int());
assert_eq!(-1_i32, N1::to_int());
assert_eq!(-2_i32, N2::to_int());
assert_eq!(-3_i32, N3::to_int());
assert_eq!(-4_i32, N4::to_int());

// i64
assert_eq!(0_i64, Z0::to_int());
assert_eq!(1_i64, P1::to_int());
assert_eq!(2_i64, P2::to_int());
assert_eq!(3_i64, P3::to_int());
assert_eq!(4_i64, P4::to_int());
assert_eq!(-1_i64, N1::to_int());
assert_eq!(-2_i64, N2::to_int());
assert_eq!(-3_i64, N3::to_int());
assert_eq!(-4_i64, N4::to_int());
}
}
11 changes: 10 additions & 1 deletion src/type_operators.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Useful **type operators** that are not defined in `core::ops`.
//!
use private::{Internal, InternalMarker};
use {Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0};
Expand Down Expand Up @@ -558,3 +557,13 @@ pub trait Gcd<Rhs> {
/// The greatest common divisor.
type Output;
}

/// A **type operator** for taking a concrete integer value from a type.
///
/// It returns arbitrary integer value without explicitly specifying the
/// type. It is useful when you pass the values to methods that accept
/// distinct types without runtime casting.
pub trait ToInt<T> {
/// Method returning the concrete value for the type.
fn to_int() -> T;
}
Loading

0 comments on commit 466df16

Please sign in to comment.