floaty/
lib.rs

1//! A trait that abstracts over the common functionality of `f32` and `f64`
2//!
3//! The `Floaty` trait provided in this crate is similar to the deprecated `std::num::Float`, but
4//! contains more information about cast operations.
5
6#![deny(warnings)]
7
8#![cfg_attr(feature = "unstable", feature(op_assign_traits))]
9
10extern crate cast;
11
12use std::num::FpCategory;
13use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
14#[cfg(feature = "unstable")]
15use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
16
17use cast::From;
18
19macro_rules! self_self {
20    ($ty:ty, $($method:ident),+) => {
21        $(
22            fn $method(self) -> $ty { self.$method() }
23         )+
24    }
25}
26
27macro_rules! self_self_self {
28    ($ty:ty, $($method:ident),+) => {
29        $(
30            fn $method(self, _1: Self) -> $ty { self.$method(_1) }
31         )+
32    }
33}
34
35macro_rules! self_bool {
36    ($ty:ty, $($method:ident),+) => {
37        $(
38            fn $method(self) -> bool { self.$method() }
39         )+
40    }
41}
42
43/// A floating point number
44#[cfg(not(feature = "unstable"))]
45pub trait Floaty
46    : Add<Output=Self>
47    + Clone
48    + Copy
49    + Div<Output=Self>
50    + From<f32, Output=Self>
51    + From<i16, Output=Self>
52    + From<i32, Output=Self>
53    + From<i64, Output=Self>
54    + From<i8, Output=Self>
55    + From<isize, Output=Self>
56    + From<u16, Output=Self>
57    + From<u32, Output=Self>
58    + From<u64, Output=Self>
59    + From<u8, Output=Self>
60    + From<usize, Output=Self>
61    + Mul<Output=Self>
62    + Neg<Output=Self>
63    + PartialEq
64    + PartialOrd
65    + Rem<Output=Self>
66    + Send
67    + Sub<Output=Self>
68    + Sync
69{
70    // `fn(self) -> Self`
71    fn abs(self) -> Self;
72    fn acos(self) -> Self;
73    fn acosh(self) -> Self;
74    fn asin(self) -> Self;
75    fn asinh(self) -> Self;
76    fn atan(self) -> Self;
77    fn atanh(self) -> Self;
78    fn cbrt(self) -> Self;
79    fn ceil(self) -> Self;
80    fn cos(self) -> Self;
81    fn cosh(self) -> Self;
82    fn exp(self) -> Self;
83    fn exp2(self) -> Self;
84    fn exp_m1(self) -> Self;
85    fn floor(self) -> Self;
86    fn fract(self) -> Self;
87    fn ln(self) -> Self;
88    fn ln_1p(self) -> Self;
89    fn log10(self) -> Self;
90    fn log2(self) -> Self;
91    fn recip(self) -> Self;
92    fn round(self) -> Self;
93    fn signum(self) -> Self;
94    fn sin(self) -> Self;
95    fn sinh(self) -> Self;
96    fn sqrt(self) -> Self;
97    fn tan(self) -> Self;
98    fn tanh(self) -> Self;
99    fn trunc(self) -> Self;
100    // TODO rust-1.7.0: remove cfg
101    #[cfg(feature = "unstable")]
102    fn to_degrees(self) -> Self;
103    // TODO rust-1.7.0: remove cfg
104    #[cfg(feature = "unstable")]
105    fn to_radians(self) -> Self;
106
107    // `fn(self, Self) -> Self`
108    fn abs_sub(self, Self) -> Self;
109    fn atan2(self, Self) -> Self;
110    fn hypot(self, Self) -> Self;
111    fn log(self, Self) -> Self;
112    fn max(self, Self) -> Self;
113    fn min(self, Self) -> Self;
114    fn powf(self, Self) -> Self;
115
116    // `fn(self) -> bool`
117    fn is_finite(self) -> bool;
118    fn is_infinite(self) -> bool;
119    fn is_nan(self) -> bool;
120    fn is_normal(self) -> bool;
121    fn is_sign_negative(self) -> bool;
122    fn is_sign_positive(self) -> bool;
123
124    // Others
125    fn classify(self) -> FpCategory;
126    fn mul_add(self, Self, Self) -> Self;
127    fn powi(self, i32) -> Self;
128    fn sin_cos(self) -> (Self, Self);
129}
130
131/// A floating point number
132#[cfg(feature = "unstable")]
133pub trait Floaty
134    : Add<Output=Self>
135    + AddAssign
136    + Clone
137    + Copy
138    + Div<Output=Self>
139    + DivAssign
140    + From<f32, Output=Self>
141    + From<i16, Output=Self>
142    + From<i32, Output=Self>
143    + From<i64, Output=Self>
144    + From<i8, Output=Self>
145    + From<isize, Output=Self>
146    + From<u16, Output=Self>
147    + From<u32, Output=Self>
148    + From<u64, Output=Self>
149    + From<u8, Output=Self>
150    + From<usize, Output=Self>
151    + Mul<Output=Self>
152    + MulAssign
153    + Neg<Output=Self>
154    + PartialEq
155    + PartialOrd
156    + Rem<Output=Self>
157    + RemAssign
158    + Send
159    + Sub<Output=Self>
160    + SubAssign
161    + Sync
162{
163    // `fn(self) -> Self`
164    fn abs(self) -> Self;
165    fn acos(self) -> Self;
166    fn acosh(self) -> Self;
167    fn asin(self) -> Self;
168    fn asinh(self) -> Self;
169    fn atan(self) -> Self;
170    fn atanh(self) -> Self;
171    fn cbrt(self) -> Self;
172    fn ceil(self) -> Self;
173    fn cos(self) -> Self;
174    fn cosh(self) -> Self;
175    fn exp(self) -> Self;
176    fn exp2(self) -> Self;
177    fn exp_m1(self) -> Self;
178    fn floor(self) -> Self;
179    fn fract(self) -> Self;
180    fn ln(self) -> Self;
181    fn ln_1p(self) -> Self;
182    fn log10(self) -> Self;
183    fn log2(self) -> Self;
184    fn recip(self) -> Self;
185    fn round(self) -> Self;
186    fn signum(self) -> Self;
187    fn sin(self) -> Self;
188    fn sinh(self) -> Self;
189    fn sqrt(self) -> Self;
190    fn tan(self) -> Self;
191    fn tanh(self) -> Self;
192    fn trunc(self) -> Self;
193    // TODO rust-1.7.0: remove cfg
194    #[cfg(feature = "unstable")]
195    fn to_degrees(self) -> Self;
196    // TODO rust-1.7.0: remove cfg
197    #[cfg(feature = "unstable")]
198    fn to_radians(self) -> Self;
199
200    // `fn(self, Self) -> Self`
201    fn abs_sub(self, Self) -> Self;
202    fn atan2(self, Self) -> Self;
203    fn hypot(self, Self) -> Self;
204    fn log(self, Self) -> Self;
205    fn max(self, Self) -> Self;
206    fn min(self, Self) -> Self;
207    fn powf(self, Self) -> Self;
208
209    // `fn(self) -> bool`
210    fn is_finite(self) -> bool;
211    fn is_infinite(self) -> bool;
212    fn is_nan(self) -> bool;
213    fn is_normal(self) -> bool;
214    fn is_sign_negative(self) -> bool;
215    fn is_sign_positive(self) -> bool;
216
217    // Others
218    fn classify(self) -> FpCategory;
219    fn mul_add(self, Self, Self) -> Self;
220    fn powi(self, i32) -> Self;
221    fn sin_cos(self) -> (Self, Self);
222}
223
224impl Floaty for f32 {
225    self_self! {
226        f32, abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, exp, exp2, exp_m1,
227        floor, fract, ln, ln_1p, log10, log2, recip, round, signum, sin, sinh, sqrt, tan, tanh,
228        trunc
229    }
230
231    #[cfg(feature = "unstable")]
232    self_self!(f32, to_degrees, to_radians);
233
234    self_self_self! {
235        f32, abs_sub, atan2, hypot, log, max, min, powf
236    }
237
238    self_bool! {
239        f32, is_finite, is_infinite, is_nan, is_normal, is_sign_negative, is_sign_positive
240    }
241
242    fn classify(self) -> FpCategory {
243        self.classify()
244    }
245    fn mul_add(self, a: f32, b: f32) -> f32 {
246        self.mul_add(a, b)
247    }
248    fn powi(self, n: i32) -> f32 {
249        self.powi(n)
250    }
251    fn sin_cos(self) -> (f32, f32) {
252        self.sin_cos()
253    }
254}
255
256impl Floaty for f64 {
257    self_self! {
258        f64, abs, acos, acosh, asin, asinh, atan, atanh, cbrt, ceil, cos, cosh, exp, exp2, exp_m1,
259        floor, fract, ln, ln_1p, log10, log2, recip, round, signum, sin, sinh, sqrt, tan, tanh,
260        trunc
261    }
262
263    #[cfg(feature = "unstable")]
264    self_self!(f64, to_degrees, to_radians);
265
266    self_self_self! {
267        f64, abs_sub, atan2, hypot, log, max, min, powf
268    }
269
270    self_bool! {
271        f64, is_finite, is_infinite, is_nan, is_normal, is_sign_negative, is_sign_positive
272    }
273
274    fn classify(self) -> FpCategory {
275        self.classify()
276    }
277    fn mul_add(self, a: f64, b: f64) -> f64 {
278        self.mul_add(a, b)
279    }
280    fn powi(self, n: i32) -> f64 {
281        self.powi(n)
282    }
283    fn sin_cos(self) -> (f64, f64) {
284        self.sin_cos()
285    }
286}