1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::ops::Neg;

/// Sign trait
pub trait Sign: Sized + Neg<Output = Self>
{
    /// Returns the sign of a number
    ///
    /// # Param
    ///
    /// # Return
    ///
    /// -1 if self < 0
    /// 0 if self = 0
    /// 1 if self > 0
    fn sign(self: &Self) -> Self;

    fn abs(self: &Self) -> Self;

    fn is_positive(self: &Self) -> bool;

    fn is_negative(self: &Self) -> bool;
}

macro_rules! impl_sign
{
    ($neg:expr; $zero:expr; $pos:expr; $($t:ty),*) =>
    {
        $(
        impl Sign for $t
        {
			fn sign(self: &Self) -> Self
			{
 				match *self
 				{
                    n if n > $zero => $pos,
                    n if n >= $zero && n <= $zero => $zero, //float comparing is not allowed anymore
                    _ => $neg,
                }
			}

			fn abs(self: &Self) -> Self
			{
				if self.is_negative()
				{
					return -*self;
				}
				return *self;
			}

            fn is_positive(self: &Self) -> bool
            {
            	return *self > $zero;
            }

            fn is_negative(&self) -> bool
            {
            	return *self < $zero;
            }
        }
        )*
    };
}

impl_sign!(-1; 0; 1; i8, i16, i32, i64, i128);

impl_sign!(-1.0; 0.0; 1.0; f32, f64);