]> git.proxmox.com Git - rustc.git/blob - vendor/num-traits/src/lib.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / num-traits / src / lib.rs
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Numeric traits for generic mathematics
12 //!
13 //! ## Compatibility
14 //!
15 //! The `num-traits` crate is tested for rustc 1.8 and greater.
16
17 #![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
18 #![deny(unconditional_recursion)]
19 #![no_std]
20 #[cfg(feature = "std")]
21 extern crate std;
22
23 // Only `no_std` builds actually use `libm`.
24 #[cfg(all(not(feature = "std"), feature = "libm"))]
25 extern crate libm;
26
27 use core::fmt;
28 use core::num::Wrapping;
29 use core::ops::{Add, Div, Mul, Rem, Sub};
30 use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
31
32 pub use bounds::Bounded;
33 #[cfg(any(feature = "std", feature = "libm"))]
34 pub use float::Float;
35 pub use float::FloatConst;
36 // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
37 pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
38 pub use identities::{one, zero, One, Zero};
39 pub use int::PrimInt;
40 pub use ops::checked::{
41 CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
42 };
43 pub use ops::inv::Inv;
44 pub use ops::mul_add::{MulAdd, MulAddAssign};
45 pub use ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
46 pub use ops::wrapping::{
47 WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
48 };
49 pub use pow::{checked_pow, pow, Pow};
50 pub use sign::{abs, abs_sub, signum, Signed, Unsigned};
51
52 #[macro_use]
53 mod macros;
54
55 pub mod bounds;
56 pub mod cast;
57 pub mod float;
58 pub mod identities;
59 pub mod int;
60 pub mod ops;
61 pub mod pow;
62 pub mod real;
63 pub mod sign;
64
65 /// The base trait for numeric types, covering `0` and `1` values,
66 /// comparisons, basic numeric operations, and string conversion.
67 pub trait Num: PartialEq + Zero + One + NumOps {
68 type FromStrRadixErr;
69
70 /// Convert from a string and radix (typically `2..=36`).
71 ///
72 /// # Examples
73 ///
74 /// ```rust
75 /// use num_traits::Num;
76 ///
77 /// let result = <i32 as Num>::from_str_radix("27", 10);
78 /// assert_eq!(result, Ok(27));
79 ///
80 /// let result = <i32 as Num>::from_str_radix("foo", 10);
81 /// assert!(result.is_err());
82 /// ```
83 ///
84 /// # Supported radices
85 ///
86 /// The exact range of supported radices is at the discretion of each type implementation. For
87 /// primitive integers, this is implemented by the inherent `from_str_radix` methods in the
88 /// standard library, which **panic** if the radix is not in the range from 2 to 36. The
89 /// implementation in this crate for primitive floats is similar.
90 ///
91 /// For third-party types, it is suggested that implementations should follow suit and at least
92 /// accept `2..=36` without panicking, but an `Err` may be returned for any unsupported radix.
93 /// It's possible that a type might not even support the common radix 10, nor any, if string
94 /// parsing doesn't make sense for that type.
95 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
96 }
97
98 /// The trait for types implementing basic numeric operations
99 ///
100 /// This is automatically implemented for types which implement the operators.
101 pub trait NumOps<Rhs = Self, Output = Self>:
102 Add<Rhs, Output = Output>
103 + Sub<Rhs, Output = Output>
104 + Mul<Rhs, Output = Output>
105 + Div<Rhs, Output = Output>
106 + Rem<Rhs, Output = Output>
107 {
108 }
109
110 impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
111 T: Add<Rhs, Output = Output>
112 + Sub<Rhs, Output = Output>
113 + Mul<Rhs, Output = Output>
114 + Div<Rhs, Output = Output>
115 + Rem<Rhs, Output = Output>
116 {
117 }
118
119 /// The trait for `Num` types which also implement numeric operations taking
120 /// the second operand by reference.
121 ///
122 /// This is automatically implemented for types which implement the operators.
123 pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
124 impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
125
126 /// The trait for references which implement numeric operations, taking the
127 /// second operand either by value or by reference.
128 ///
129 /// This is automatically implemented for types which implement the operators.
130 pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
131 impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
132
133 /// The trait for types implementing numeric assignment operators (like `+=`).
134 ///
135 /// This is automatically implemented for types which implement the operators.
136 pub trait NumAssignOps<Rhs = Self>:
137 AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
138 {
139 }
140
141 impl<T, Rhs> NumAssignOps<Rhs> for T where
142 T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
143 {
144 }
145
146 /// The trait for `Num` types which also implement assignment operators.
147 ///
148 /// This is automatically implemented for types which implement the operators.
149 pub trait NumAssign: Num + NumAssignOps {}
150 impl<T> NumAssign for T where T: Num + NumAssignOps {}
151
152 /// The trait for `NumAssign` types which also implement assignment operations
153 /// taking the second operand by reference.
154 ///
155 /// This is automatically implemented for types which implement the operators.
156 pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
157 impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
158
159 macro_rules! int_trait_impl {
160 ($name:ident for $($t:ty)*) => ($(
161 impl $name for $t {
162 type FromStrRadixErr = ::core::num::ParseIntError;
163 #[inline]
164 fn from_str_radix(s: &str, radix: u32)
165 -> Result<Self, ::core::num::ParseIntError>
166 {
167 <$t>::from_str_radix(s, radix)
168 }
169 }
170 )*)
171 }
172 int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
173 #[cfg(has_i128)]
174 int_trait_impl!(Num for u128 i128);
175
176 impl<T: Num> Num for Wrapping<T>
177 where
178 Wrapping<T>: Add<Output = Wrapping<T>>
179 + Sub<Output = Wrapping<T>>
180 + Mul<Output = Wrapping<T>>
181 + Div<Output = Wrapping<T>>
182 + Rem<Output = Wrapping<T>>,
183 {
184 type FromStrRadixErr = T::FromStrRadixErr;
185 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
186 T::from_str_radix(str, radix).map(Wrapping)
187 }
188 }
189
190 #[derive(Debug)]
191 pub enum FloatErrorKind {
192 Empty,
193 Invalid,
194 }
195 // FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
196 // so there's not really any way for us to reuse it.
197 #[derive(Debug)]
198 pub struct ParseFloatError {
199 pub kind: FloatErrorKind,
200 }
201
202 impl fmt::Display for ParseFloatError {
203 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
204 let description = match self.kind {
205 FloatErrorKind::Empty => "cannot parse float from empty string",
206 FloatErrorKind::Invalid => "invalid float literal",
207 };
208
209 description.fmt(f)
210 }
211 }
212
213 // FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
214 // with this implementation ourselves until we want to make a breaking change.
215 // (would have to drop it from `Num` though)
216 macro_rules! float_trait_impl {
217 ($name:ident for $($t:ident)*) => ($(
218 impl $name for $t {
219 type FromStrRadixErr = ParseFloatError;
220
221 fn from_str_radix(src: &str, radix: u32)
222 -> Result<Self, Self::FromStrRadixErr>
223 {
224 use self::FloatErrorKind::*;
225 use self::ParseFloatError as PFE;
226
227 // Special values
228 match src {
229 "inf" => return Ok(core::$t::INFINITY),
230 "-inf" => return Ok(core::$t::NEG_INFINITY),
231 "NaN" => return Ok(core::$t::NAN),
232 _ => {},
233 }
234
235 fn slice_shift_char(src: &str) -> Option<(char, &str)> {
236 let mut chars = src.chars();
237 if let Some(ch) = chars.next() {
238 Some((ch, chars.as_str()))
239 } else {
240 None
241 }
242 }
243
244 let (is_positive, src) = match slice_shift_char(src) {
245 None => return Err(PFE { kind: Empty }),
246 Some(('-', "")) => return Err(PFE { kind: Empty }),
247 Some(('-', src)) => (false, src),
248 Some((_, _)) => (true, src),
249 };
250
251 // The significand to accumulate
252 let mut sig = if is_positive { 0.0 } else { -0.0 };
253 // Necessary to detect overflow
254 let mut prev_sig = sig;
255 let mut cs = src.chars().enumerate();
256 // Exponent prefix and exponent index offset
257 let mut exp_info = None::<(char, usize)>;
258
259 // Parse the integer part of the significand
260 for (i, c) in cs.by_ref() {
261 match c.to_digit(radix) {
262 Some(digit) => {
263 // shift significand one digit left
264 sig = sig * (radix as $t);
265
266 // add/subtract current digit depending on sign
267 if is_positive {
268 sig = sig + ((digit as isize) as $t);
269 } else {
270 sig = sig - ((digit as isize) as $t);
271 }
272
273 // Detect overflow by comparing to last value, except
274 // if we've not seen any non-zero digits.
275 if prev_sig != 0.0 {
276 if is_positive && sig <= prev_sig
277 { return Ok(core::$t::INFINITY); }
278 if !is_positive && sig >= prev_sig
279 { return Ok(core::$t::NEG_INFINITY); }
280
281 // Detect overflow by reversing the shift-and-add process
282 if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
283 { return Ok(core::$t::INFINITY); }
284 if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
285 { return Ok(core::$t::NEG_INFINITY); }
286 }
287 prev_sig = sig;
288 },
289 None => match c {
290 'e' | 'E' | 'p' | 'P' => {
291 exp_info = Some((c, i + 1));
292 break; // start of exponent
293 },
294 '.' => {
295 break; // start of fractional part
296 },
297 _ => {
298 return Err(PFE { kind: Invalid });
299 },
300 },
301 }
302 }
303
304 // If we are not yet at the exponent parse the fractional
305 // part of the significand
306 if exp_info.is_none() {
307 let mut power = 1.0;
308 for (i, c) in cs.by_ref() {
309 match c.to_digit(radix) {
310 Some(digit) => {
311 // Decrease power one order of magnitude
312 power = power / (radix as $t);
313 // add/subtract current digit depending on sign
314 sig = if is_positive {
315 sig + (digit as $t) * power
316 } else {
317 sig - (digit as $t) * power
318 };
319 // Detect overflow by comparing to last value
320 if is_positive && sig < prev_sig
321 { return Ok(core::$t::INFINITY); }
322 if !is_positive && sig > prev_sig
323 { return Ok(core::$t::NEG_INFINITY); }
324 prev_sig = sig;
325 },
326 None => match c {
327 'e' | 'E' | 'p' | 'P' => {
328 exp_info = Some((c, i + 1));
329 break; // start of exponent
330 },
331 _ => {
332 return Err(PFE { kind: Invalid });
333 },
334 },
335 }
336 }
337 }
338
339 // Parse and calculate the exponent
340 let exp = match exp_info {
341 Some((c, offset)) => {
342 let base = match c {
343 'E' | 'e' if radix == 10 => 10.0,
344 'P' | 'p' if radix == 16 => 2.0,
345 _ => return Err(PFE { kind: Invalid }),
346 };
347
348 // Parse the exponent as decimal integer
349 let src = &src[offset..];
350 let (is_positive, exp) = match slice_shift_char(src) {
351 Some(('-', src)) => (false, src.parse::<usize>()),
352 Some(('+', src)) => (true, src.parse::<usize>()),
353 Some((_, _)) => (true, src.parse::<usize>()),
354 None => return Err(PFE { kind: Invalid }),
355 };
356
357 #[cfg(feature = "std")]
358 fn pow(base: $t, exp: usize) -> $t {
359 Float::powi(base, exp as i32)
360 }
361 // otherwise uses the generic `pow` from the root
362
363 match (is_positive, exp) {
364 (true, Ok(exp)) => pow(base, exp),
365 (false, Ok(exp)) => 1.0 / pow(base, exp),
366 (_, Err(_)) => return Err(PFE { kind: Invalid }),
367 }
368 },
369 None => 1.0, // no exponent
370 };
371
372 Ok(sig * exp)
373 }
374 }
375 )*)
376 }
377 float_trait_impl!(Num for f32 f64);
378
379 /// A value bounded by a minimum and a maximum
380 ///
381 /// If input is less than min then this returns min.
382 /// If input is greater than max then this returns max.
383 /// Otherwise this returns input.
384 ///
385 /// **Panics** in debug mode if `!(min <= max)`.
386 #[inline]
387 pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
388 debug_assert!(min <= max, "min must be less than or equal to max");
389 if input < min {
390 min
391 } else if input > max {
392 max
393 } else {
394 input
395 }
396 }
397
398 /// A value bounded by a minimum value
399 ///
400 /// If input is less than min then this returns min.
401 /// Otherwise this returns input.
402 /// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
403 ///
404 /// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
405 #[inline]
406 pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
407 debug_assert!(min == min, "min must not be NAN");
408 if input < min {
409 min
410 } else {
411 input
412 }
413 }
414
415 /// A value bounded by a maximum value
416 ///
417 /// If input is greater than max then this returns max.
418 /// Otherwise this returns input.
419 /// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
420 ///
421 /// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
422 #[inline]
423 pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
424 debug_assert!(max == max, "max must not be NAN");
425 if input > max {
426 max
427 } else {
428 input
429 }
430 }
431
432 #[test]
433 fn clamp_test() {
434 // Int test
435 assert_eq!(1, clamp(1, -1, 2));
436 assert_eq!(-1, clamp(-2, -1, 2));
437 assert_eq!(2, clamp(3, -1, 2));
438 assert_eq!(1, clamp_min(1, -1));
439 assert_eq!(-1, clamp_min(-2, -1));
440 assert_eq!(-1, clamp_max(1, -1));
441 assert_eq!(-2, clamp_max(-2, -1));
442
443 // Float test
444 assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
445 assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
446 assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
447 assert_eq!(1.0, clamp_min(1.0, -1.0));
448 assert_eq!(-1.0, clamp_min(-2.0, -1.0));
449 assert_eq!(-1.0, clamp_max(1.0, -1.0));
450 assert_eq!(-2.0, clamp_max(-2.0, -1.0));
451 assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
452 assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
453 assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
454 }
455
456 #[test]
457 #[should_panic]
458 #[cfg(debug_assertions)]
459 fn clamp_nan_min() {
460 clamp(0., ::core::f32::NAN, 1.);
461 }
462
463 #[test]
464 #[should_panic]
465 #[cfg(debug_assertions)]
466 fn clamp_nan_max() {
467 clamp(0., -1., ::core::f32::NAN);
468 }
469
470 #[test]
471 #[should_panic]
472 #[cfg(debug_assertions)]
473 fn clamp_nan_min_max() {
474 clamp(0., ::core::f32::NAN, ::core::f32::NAN);
475 }
476
477 #[test]
478 #[should_panic]
479 #[cfg(debug_assertions)]
480 fn clamp_min_nan_min() {
481 clamp_min(0., ::core::f32::NAN);
482 }
483
484 #[test]
485 #[should_panic]
486 #[cfg(debug_assertions)]
487 fn clamp_max_nan_max() {
488 clamp_max(0., ::core::f32::NAN);
489 }
490
491 #[test]
492 fn from_str_radix_unwrap() {
493 // The Result error must impl Debug to allow unwrap()
494
495 let i: i32 = Num::from_str_radix("0", 10).unwrap();
496 assert_eq!(i, 0);
497
498 let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
499 assert_eq!(f, 0.0);
500 }
501
502 #[test]
503 fn from_str_radix_multi_byte_fail() {
504 // Ensure parsing doesn't panic, even on invalid sign characters
505 assert!(f32::from_str_radix("™0.2", 10).is_err());
506
507 // Even when parsing the exponent sign
508 assert!(f32::from_str_radix("0.2E™1", 10).is_err());
509 }
510
511 #[test]
512 fn wrapping_is_num() {
513 fn require_num<T: Num>(_: &T) {}
514 require_num(&Wrapping(42_u32));
515 require_num(&Wrapping(-42));
516 }
517
518 #[test]
519 fn wrapping_from_str_radix() {
520 macro_rules! test_wrapping_from_str_radix {
521 ($($t:ty)+) => {
522 $(
523 for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
524 let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
525 assert_eq!(w, <$t as Num>::from_str_radix(s, r));
526 }
527 )+
528 };
529 }
530
531 test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
532 }
533
534 #[test]
535 fn check_num_ops() {
536 fn compute<T: Num + Copy>(x: T, y: T) -> T {
537 x * y / y % y + y - y
538 }
539 assert_eq!(compute(1, 2), 1)
540 }
541
542 #[test]
543 fn check_numref_ops() {
544 fn compute<T: NumRef>(x: T, y: &T) -> T {
545 x * y / y % y + y - y
546 }
547 assert_eq!(compute(1, &2), 1)
548 }
549
550 #[test]
551 fn check_refnum_ops() {
552 fn compute<T: Copy>(x: &T, y: T) -> T
553 where
554 for<'a> &'a T: RefNum<T>,
555 {
556 &(&(&(&(x * y) / y) % y) + y) - y
557 }
558 assert_eq!(compute(&1, 2), 1)
559 }
560
561 #[test]
562 fn check_refref_ops() {
563 fn compute<T>(x: &T, y: &T) -> T
564 where
565 for<'a> &'a T: RefNum<T>,
566 {
567 &(&(&(&(x * y) / y) % y) + y) - y
568 }
569 assert_eq!(compute(&1, &2), 1)
570 }
571
572 #[test]
573 fn check_numassign_ops() {
574 fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
575 x *= y;
576 x /= y;
577 x %= y;
578 x += y;
579 x -= y;
580 x
581 }
582 assert_eq!(compute(1, 2), 1)
583 }
584
585 // TODO test `NumAssignRef`, but even the standard numeric types don't
586 // implement this yet. (see rust pr41336)