const_identities/
lib.rs

1//! Extends the traits from [`num_traits::identities`] to use an associated constant.
2//!
3//! [`num_traits::identities`]: https://rust-num.github.io/num/num_traits/identities/index.html
4//!
5//! # Examples
6//!
7//! ```rust
8//! #![feature(const_fn)]
9//!
10//! # extern crate const_identities;
11//! use const_identities::ConstZero;
12//!
13//! pub struct Newtype<T>(pub T);
14//!
15//! impl<T: ConstZero> Newtype<T> {
16//!     pub const fn zero() -> Self {
17//!         Newtype(T::ZERO)
18//!     }
19//! }
20//!
21//! assert_eq!(Newtype::<i32>::zero().0, 0);
22//! ```
23
24extern crate num_traits;
25extern crate num_complex;
26
27use std::ops;
28use std::num::Wrapping;
29
30use num_traits::{Num, identities::{Zero, One}};
31use num_complex::Complex;
32
33/// The additive identity element for `Self`, expressed as an associated constant.
34pub trait ConstZero: Zero {
35    /// The additive identity.
36    const ZERO: Self;
37}
38
39/// The multiplicative identity element for `Self`, expressed as an associated constant.
40pub trait ConstOne: One {
41    /// The multiplicative identity.
42    const ONE: Self;
43}
44
45macro_rules! const_zero_one {
46    (
47        ($zero:expr, $one:expr) => [
48            $( $T:ident ),* $(,)*
49        ]
50    ) => {
51        $(
52            impl ConstZero for $T {
53                const ZERO: Self = $zero;
54            }
55
56            impl ConstOne for $T {
57                const ONE: Self = $one;
58            }
59         )*
60    }
61}
62
63const_zero_one! {
64    (0, 1) => [
65        i8, i16, i32, i64, isize,
66        u8, u16, u32, u64, usize,
67    ]
68}
69
70const_zero_one! {
71    (0., 1.) => [f32, f64]
72}
73
74impl<T> ConstZero for Wrapping<T>
75    where T: ConstZero,
76          Wrapping<T>: ops::Add<Output=Wrapping<T>>,
77{
78    const ZERO: Self = Wrapping(T::ZERO);
79}
80
81impl<T> ConstOne for Wrapping<T>
82    where T: ConstOne,
83          Wrapping<T>: ops::Mul<Output=Wrapping<T>>,
84{
85    const ONE: Self = Wrapping(T::ONE);
86}
87
88impl<T> ConstZero for Complex<T>
89    where T: Clone + Num + ConstZero
90{
91    const ZERO: Self = Complex { re: T::ZERO, im: T::ZERO };
92}
93
94impl<T> ConstOne for Complex<T>
95    where T: Clone + Num + ConstZero + ConstOne
96{
97    const ONE: Self = Complex { re: T::ONE, im: T::ZERO };
98}