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