[types] Make math ops macros even more generic -- implement them for cross types too!
Still need to write tests for this though.
This commit is contained in:
		
							parent
							
								
									9d40cdd995
								
							
						
					
					
						commit
						c07e6aa99b
					
				
					 5 changed files with 33 additions and 18 deletions
				
			
		|  | @ -3,7 +3,7 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::ops::{Add, Div, Mul, Sub, Rem}; | use std::ops::{Add, Div, Mul, Sub, Rem}; | ||||||
| use number::{Int, Irr}; | use number::{Int, Irr, Number}; | ||||||
| 
 | 
 | ||||||
| pub trait GCD { | pub trait GCD { | ||||||
|     /// Find the greatest common divisor of `self` and another number.
 |     /// Find the greatest common divisor of `self` and another number.
 | ||||||
|  | @ -17,24 +17,19 @@ pub trait LCM { | ||||||
| 
 | 
 | ||||||
| macro_rules! impl_newtype_arith_op { | macro_rules! impl_newtype_arith_op { | ||||||
|     ($id:ident, $opt:ident, $opm:ident, $op:tt) => { |     ($id:ident, $opt:ident, $opm:ident, $op:tt) => { | ||||||
|         impl $opt for $id { |         impl<T> $opt<T> for $id where T: Number + Into<$id> { | ||||||
|             type Output = $id; |             type Output = $id; | ||||||
|             #[inline] |             #[inline] | ||||||
|             fn $opm(self, rhs: $id) -> Self::Output { |             fn $opm(self, rhs: T) -> Self::Output { | ||||||
|  |                 let rhs: $id = rhs.into(); | ||||||
|                 $id(self.0 $op rhs.0) |                 $id(self.0 $op rhs.0) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         impl<'a> $opt<$id> for &'a $id { |         impl<'a, T> $opt<T> for &'a $id where T: Number + Into<$id> { | ||||||
|             type Output = $id; |             type Output = $id; | ||||||
|             #[inline] |             #[inline] | ||||||
|             fn $opm(self, rhs: $id) -> Self::Output { |             fn $opm(self, rhs: T) -> Self::Output { | ||||||
|                 $id(self.0 $op rhs.0) |                 let rhs: $id = rhs.into(); | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         impl<'a, 'b> $opt<&'a $id> for &'b $id { |  | ||||||
|             type Output = $id; |  | ||||||
|             #[inline] |  | ||||||
|             fn $opm(self, rhs: &$id) -> Self::Output { |  | ||||||
|                 $id(self.0 $op rhs.0) |                 $id(self.0 $op rhs.0) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -32,6 +32,10 @@ impl Frac { | ||||||
|         Frac::new(Int(p), Int(q)) |         Frac::new(Int(p), Int(q)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn quotient(&self) -> f64 { | ||||||
|  |         self.p.0 as f64 / self.q.0 as f64 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn reduced(self) -> Frac { |     fn reduced(self) -> Frac { | ||||||
|         let gcd = self.p.gcd(self.q); |         let gcd = self.p.gcd(self.q); | ||||||
|         Frac { p: self.p / gcd, q: self.q / gcd } |         Frac { p: self.p / gcd, q: self.q / gcd } | ||||||
|  | @ -77,6 +81,12 @@ impl fmt::Display for Frac { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl From<Int> for Frac { | ||||||
|  |     fn from(i: Int) -> Frac { | ||||||
|  |         Frac{p: i, q: Int(1)} | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl Mul for Frac { | impl Mul for Frac { | ||||||
|     type Output = Frac; |     type Output = Frac; | ||||||
|     fn mul(self, rhs: Self) -> Self::Output { |     fn mul(self, rhs: Self) -> Self::Output { | ||||||
|  |  | ||||||
|  | @ -5,8 +5,8 @@ | ||||||
| use std::any::Any; | use std::any::Any; | ||||||
| use std::fmt; | use std::fmt; | ||||||
| use number::arith::{GCD, LCM}; | use number::arith::{GCD, LCM}; | ||||||
| use number::{Frac, Number}; |  | ||||||
| use object::{Obj, Object}; | use object::{Obj, Object}; | ||||||
|  | use super::{Frac, Number}; | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] | #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] | ||||||
| pub struct Int(pub i64); | pub struct Int(pub i64); | ||||||
|  |  | ||||||
|  | @ -20,9 +20,14 @@ impl fmt::Display for Irr { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Object for Irr { | impl From<Int> for Irr { | ||||||
|     fn as_any(&self) -> &Any { self } |     fn from(i: Int) -> Irr { Irr(i.0 as f64) } | ||||||
|     fn as_num(&self) -> Option<&Number> { Some(self) } | } | ||||||
|  | 
 | ||||||
|  | impl From<Frac> for Irr { | ||||||
|  |     fn from(f: Frac) -> Irr { | ||||||
|  |         Irr(f.quotient()) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Number for Irr { | impl Number for Irr { | ||||||
|  | @ -46,6 +51,11 @@ impl Number for Irr { | ||||||
|     fn is_zero(&self) -> bool { self.0 == 0.0 } |     fn is_zero(&self) -> bool { self.0 == 0.0 } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl Object for Irr { | ||||||
|  |     fn as_any(&self) -> &Any { self } | ||||||
|  |     fn as_num(&self) -> Option<&Number> { Some(self) } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl PartialEq<Obj> for Irr { | impl PartialEq<Obj> for Irr { | ||||||
|     fn eq<'a>(&self, rhs: &'a Obj) -> bool { |     fn eq<'a>(&self, rhs: &'a Obj) -> bool { | ||||||
|         match rhs.obj().and_then(Object::as_num) { |         match rhs.obj().and_then(Object::as_num) { | ||||||
|  |  | ||||||
|  | @ -11,13 +11,13 @@ | ||||||
| //! Integer can be cast as a Rational (by putting its value over 1), but a Rational like 1/2 cannot
 | //! Integer can be cast as a Rational (by putting its value over 1), but a Rational like 1/2 cannot
 | ||||||
| //! be represented as an Integer.
 | //! be represented as an Integer.
 | ||||||
| 
 | 
 | ||||||
|  | use object::Object; | ||||||
|  | 
 | ||||||
| mod arith; | mod arith; | ||||||
| mod frac; | mod frac; | ||||||
| mod integer; | mod integer; | ||||||
| mod irr; | mod irr; | ||||||
| 
 | 
 | ||||||
| use object::Object; |  | ||||||
| 
 |  | ||||||
| pub use self::frac::Frac; | pub use self::frac::Frac; | ||||||
| pub use self::integer::Int; | pub use self::integer::Int; | ||||||
| pub use self::irr::Irr; | pub use self::irr::Irr; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue