1 //! Useful **type operators** that are not defined in `core::ops`.
2 //!
3
4 use {Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0};
5
6 /// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful
7 /// for writing macros that can take arbitrary binary or unary operators.
8 ///
9 /// `Same` is implemented generically for all types; it should never need to be implemented
10 /// for anything else.
11 ///
12 /// Note that Rust lazily evaluates types, so this will only fail for two different types if
13 /// the `Output` is used.
14 ///
15 /// # Example
16 /// ```rust
17 /// use typenum::{Same, U4, U5, Unsigned};
18 ///
19 /// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5);
20 ///
21 /// // Only an error if we use it:
22 /// # #[allow(dead_code)]
23 /// type Undefined = <U5 as Same<U4>>::Output;
24 /// // Compiler error:
25 /// // Undefined::to_u32();
26 /// ```
27 pub trait Same<Rhs = Self> {
28 /// Should always be `Self`
29 type Output;
30 }
31
32 impl<T> Same<T> for T {
33 type Output = T;
34 }
35
36 /// A **type operator** that returns the absolute value.
37 ///
38 /// # Example
39 /// ```rust
40 /// use typenum::{Abs, N5, Integer};
41 ///
42 /// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);
43 /// ```
44 pub trait Abs {
45 /// The absolute value.
46 type Output;
47 }
48
49 impl Abs for Z0 {
50 type Output = Z0;
51 }
52
53 impl<U: Unsigned + NonZero> Abs for PInt<U> {
54 type Output = Self;
55 }
56
57 impl<U: Unsigned + NonZero> Abs for NInt<U> {
58 type Output = PInt<U>;
59 }
60
61 /// A **type operator** that provides exponentiation by repeated squaring.
62 ///
63 /// # Example
64 /// ```rust
65 /// use typenum::{Pow, N3, P3, Integer};
66 ///
67 /// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);
68 /// ```
69 pub trait Pow<Exp> {
70 /// The result of the exponentiation.
71 type Output;
72 /// This function isn't used in this crate, but may be useful for others.
73 /// It is implemented for primitives.
74 ///
75 /// # Example
76 /// ```rust
77 /// use typenum::{Pow, U3};
78 ///
79 /// let a = 7u32.powi(U3::new());
80 /// let b = 7u32.pow(3);
81 /// assert_eq!(a, b);
82 ///
83 /// let x = 3.0.powi(U3::new());
84 /// let y = 27.0;
85 /// assert_eq!(x, y);
86 /// ```
powi(self, exp: Exp) -> Self::Output87 fn powi(self, exp: Exp) -> Self::Output;
88 }
89
90 macro_rules! impl_pow_f {
91 ($t: ty) => (
92 impl Pow<UTerm> for $t {
93 type Output = $t;
94 #[inline]
95 fn powi(self, _: UTerm) -> Self::Output {
96 1.0
97 }
98 }
99
100 impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
101 type Output = $t;
102 // powi is unstable in core, so we have to write this function ourselves.
103 // copied from num::pow::pow
104 #[inline]
105 fn powi(self, _: UInt<U, B>) -> Self::Output {
106 let mut exp = <UInt<U, B> as Unsigned>::to_u32();
107 let mut base = self;
108
109 if exp == 0 { return 1.0 }
110
111 while exp & 1 == 0 {
112 base *= base;
113 exp >>= 1;
114 }
115 if exp == 1 { return base }
116
117 let mut acc = base.clone();
118 while exp > 1 {
119 exp >>= 1;
120 base *= base;
121 if exp & 1 == 1 {
122 acc *= base.clone();
123 }
124 }
125 acc
126 }
127 }
128
129 impl Pow<Z0> for $t {
130 type Output = $t;
131 #[inline]
132 fn powi(self, _: Z0) -> Self::Output {
133 1.0
134 }
135 }
136
137 impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
138 type Output = $t;
139 // powi is unstable in core, so we have to write this function ourselves.
140 // copied from num::pow::pow
141 #[inline]
142 fn powi(self, _: PInt<U>) -> Self::Output {
143 let mut exp = U::to_u32();
144 let mut base = self;
145
146 if exp == 0 { return 1.0 }
147
148 while exp & 1 == 0 {
149 base *= base;
150 exp >>= 1;
151 }
152 if exp == 1 { return base }
153
154 let mut acc = base.clone();
155 while exp > 1 {
156 exp >>= 1;
157 base *= base;
158 if exp & 1 == 1 {
159 acc *= base.clone();
160 }
161 }
162 acc
163 }
164 }
165 );
166 }
167
168 impl_pow_f!(f32);
169 impl_pow_f!(f64);
170
171 macro_rules! impl_pow_i {
172 () => ();
173 ($t: ty $(, $tail:tt)*) => (
174 impl Pow<UTerm> for $t {
175 type Output = $t;
176 #[inline]
177 fn powi(self, _: UTerm) -> Self::Output {
178 1
179 }
180 }
181
182 impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
183 type Output = $t;
184 #[inline]
185 fn powi(self, _: UInt<U, B>) -> Self::Output {
186 self.pow(<UInt<U, B> as Unsigned>::to_u32())
187 }
188 }
189
190 impl Pow<Z0> for $t {
191 type Output = $t;
192 #[inline]
193 fn powi(self, _: Z0) -> Self::Output {
194 1
195 }
196 }
197
198 impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
199 type Output = $t;
200 #[inline]
201 fn powi(self, _: PInt<U>) -> Self::Output {
202 self.pow(U::to_u32())
203 }
204 }
205
206 impl_pow_i!($($tail),*);
207 );
208 }
209
210 impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
211 #[cfg(feature = "i128")]
212 impl_pow_i!(u128, i128);
213
214 #[test]
pow_test()215 fn pow_test() {
216 use consts::*;
217 let z0 = Z0::new();
218 let p3 = P3::new();
219
220 let u0 = U0::new();
221 let u3 = U3::new();
222
223 macro_rules! check {
224 ($x:ident) => (
225 assert_eq!($x.powi(z0), 1);
226 assert_eq!($x.powi(u0), 1);
227
228 assert_eq!($x.powi(p3), $x*$x*$x);
229 assert_eq!($x.powi(u3), $x*$x*$x);
230 );
231 ($x:ident, $f:ident) => (
232 assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
233 assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
234
235 assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x*$x*$x).abs() < ::core::$f::EPSILON);
236 assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x*$x*$x).abs() < ::core::$f::EPSILON);
237 );
238 }
239
240 for x in &[0i8, -3, 2] {
241 check!(x);
242 }
243 for x in &[0u8, 1, 5] {
244 check!(x);
245 }
246 for x in &[0usize, 1, 5, 40] {
247 check!(x);
248 }
249 for x in &[0isize, 1, 2, -30, -22, 48] {
250 check!(x);
251 }
252 for x in &[0.0f32, 2.2, -3.5, 378.223] {
253 check!(x, f32);
254 }
255 for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
256 check!(x, f64);
257 }
258 }
259
260 /// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
261 /// the function
262 /// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
263 /// but for types.
264 ///
265 /// # Example
266 /// ```rust
267 /// use typenum::{Cmp, Ord, N3, P2, P5};
268 /// use std::cmp::Ordering;
269 ///
270 /// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
271 /// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
272 /// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
273 pub trait Cmp<Rhs = Self> {
274 /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
275 type Output;
276 }
277
278 /// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
279 pub trait Len {
280 /// The length as a type-level unsigned integer.
281 type Output: ::Unsigned;
282 /// This function isn't used in this crate, but may be useful for others.
len(&self) -> Self::Output283 fn len(&self) -> Self::Output;
284 }
285
286 /// Division as a partial function. This **type operator** performs division just as `Div`, but is
287 /// only defined when the result is an integer (i.e. there is no remainder).
288 pub trait PartialDiv<Rhs = Self> {
289 /// The type of the result of the division
290 type Output;
291 /// Method for performing the division
partial_div(self, _: Rhs) -> Self::Output292 fn partial_div(self, _: Rhs) -> Self::Output;
293 }
294
295 /// A **type operator** that returns the minimum of `Self` and `Rhs`.
296 pub trait Min<Rhs = Self> {
297 /// The type of the minimum of `Self` and `Rhs`
298 type Output;
299 /// Method returning the minimum
min(self, rhs: Rhs) -> Self::Output300 fn min(self, rhs: Rhs) -> Self::Output;
301 }
302
303 /// A **type operator** that returns the maximum of `Self` and `Rhs`.
304 pub trait Max<Rhs = Self> {
305 /// The type of the maximum of `Self` and `Rhs`
306 type Output;
307 /// Method returning the maximum
max(self, rhs: Rhs) -> Self::Output308 fn max(self, rhs: Rhs) -> Self::Output;
309 }
310
311 use Compare;
312
313 /// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
314 pub trait IsLess<Rhs = Self> {
315 /// The type representing either `True` or `False`
316 type Output: Bit;
317 /// Method returning `True` or `False`.
is_less(self, rhs: Rhs) -> Self::Output318 fn is_less(self, rhs: Rhs) -> Self::Output;
319 }
320
321 use private::IsLessPrivate;
322 impl<A, B> IsLess<B> for A
323 where
324 A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,
325 {
326 type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
327
is_less(self, _: B) -> Self::Output328 fn is_less(self, _: B) -> Self::Output {
329 unsafe { ::core::mem::uninitialized() }
330 }
331 }
332
333 /// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
334 pub trait IsEqual<Rhs = Self> {
335 /// The type representing either `True` or `False`
336 type Output: Bit;
337 /// Method returning `True` or `False`.
is_equal(self, rhs: Rhs) -> Self::Output338 fn is_equal(self, rhs: Rhs) -> Self::Output;
339 }
340
341 use private::IsEqualPrivate;
342 impl<A, B> IsEqual<B> for A
343 where
344 A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,
345 {
346 type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
347
is_equal(self, _: B) -> Self::Output348 fn is_equal(self, _: B) -> Self::Output {
349 unsafe { ::core::mem::uninitialized() }
350 }
351 }
352
353 /// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
354 pub trait IsGreater<Rhs = Self> {
355 /// The type representing either `True` or `False`
356 type Output: Bit;
357 /// Method returning `True` or `False`.
is_greater(self, rhs: Rhs) -> Self::Output358 fn is_greater(self, rhs: Rhs) -> Self::Output;
359 }
360
361 use private::IsGreaterPrivate;
362 impl<A, B> IsGreater<B> for A
363 where
364 A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,
365 {
366 type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
367
is_greater(self, _: B) -> Self::Output368 fn is_greater(self, _: B) -> Self::Output {
369 unsafe { ::core::mem::uninitialized() }
370 }
371 }
372
373 /// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
374 pub trait IsLessOrEqual<Rhs = Self> {
375 /// The type representing either `True` or `False`
376 type Output: Bit;
377 /// Method returning `True` or `False`.
is_less_or_equal(self, rhs: Rhs) -> Self::Output378 fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
379 }
380
381 use private::IsLessOrEqualPrivate;
382 impl<A, B> IsLessOrEqual<B> for A
383 where
384 A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,
385 {
386 type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
387
is_less_or_equal(self, _: B) -> Self::Output388 fn is_less_or_equal(self, _: B) -> Self::Output {
389 unsafe { ::core::mem::uninitialized() }
390 }
391 }
392
393 /// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
394 pub trait IsNotEqual<Rhs = Self> {
395 /// The type representing either `True` or `False`
396 type Output: Bit;
397 /// Method returning `True` or `False`.
is_not_equal(self, rhs: Rhs) -> Self::Output398 fn is_not_equal(self, rhs: Rhs) -> Self::Output;
399 }
400
401 use private::IsNotEqualPrivate;
402 impl<A, B> IsNotEqual<B> for A
403 where
404 A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,
405 {
406 type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
407
is_not_equal(self, _: B) -> Self::Output408 fn is_not_equal(self, _: B) -> Self::Output {
409 unsafe { ::core::mem::uninitialized() }
410 }
411 }
412
413 /// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
414 pub trait IsGreaterOrEqual<Rhs = Self> {
415 /// The type representing either `True` or `False`
416 type Output: Bit;
417 /// Method returning `True` or `False`.
is_greater_or_equal(self, rhs: Rhs) -> Self::Output418 fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
419 }
420
421 use private::IsGreaterOrEqualPrivate;
422 impl<A, B> IsGreaterOrEqual<B> for A
423 where
424 A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,
425 {
426 type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
427
is_greater_or_equal(self, _: B) -> Self::Output428 fn is_greater_or_equal(self, _: B) -> Self::Output {
429 unsafe { ::core::mem::uninitialized() }
430 }
431 }
432
433 /**
434 A convenience macro for comparing type numbers. Use `op!` instead.
435
436 Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
437 `ident`, you must place a comma between it and the comparison sign.
438
439 For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
440 `cmp!(typenum::P5 > typenum::P3)`.
441
442 The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
443
444 # Example
445 ```rust
446 #[macro_use] extern crate typenum;
447 use typenum::consts::*;
448 use typenum::Bit;
449
450 fn main() {
451 type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
452 assert_eq!(Result::to_bool(), true);
453 }
454 ```
455 */
456 #[deprecated(since = "1.9.0", note = "use the `op!` macro instead")]
457 #[macro_export]
458 macro_rules! cmp {
459 ($a:ident < $b:ty) => (
460 <$a as $crate::IsLess<$b>>::Output
461 );
462 ($a:ty, < $b:ty) => (
463 <$a as $crate::IsLess<$b>>::Output
464 );
465
466 ($a:ident == $b:ty) => (
467 <$a as $crate::IsEqual<$b>>::Output
468 );
469 ($a:ty, == $b:ty) => (
470 <$a as $crate::IsEqual<$b>>::Output
471 );
472
473 ($a:ident > $b:ty) => (
474 <$a as $crate::IsGreater<$b>>::Output
475 );
476 ($a:ty, > $b:ty) => (
477 <$a as $crate::IsGreater<$b>>::Output
478 );
479
480 ($a:ident <= $b:ty) => (
481 <$a as $crate::IsLessOrEqual<$b>>::Output
482 );
483 ($a:ty, <= $b:ty) => (
484 <$a as $crate::IsLessOrEqual<$b>>::Output
485 );
486
487 ($a:ident != $b:ty) => (
488 <$a as $crate::IsNotEqual<$b>>::Output
489 );
490 ($a:ty, != $b:ty) => (
491 <$a as $crate::IsNotEqual<$b>>::Output
492 );
493
494 ($a:ident >= $b:ty) => (
495 <$a as $crate::IsGreaterOrEqual<$b>>::Output
496 );
497 ($a:ty, >= $b:ty) => (
498 <$a as $crate::IsGreaterOrEqual<$b>>::Output
499 );
500 }
501