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 | ($t: ty $(, $tail:tt)*) => ( |
193 | impl Pow<UTerm> for $t { |
194 | type Output = $t; |
195 | #[inline] |
196 | fn powi(self, _: UTerm) -> Self::Output { |
197 | 1 |
198 | } |
199 | } |
200 | |
201 | impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t { |
202 | type Output = $t; |
203 | #[inline] |
204 | fn powi(self, _: UInt<U, B>) -> Self::Output { |
205 | self.pow(<UInt<U, B> as Unsigned>::to_u32()) |
206 | } |
207 | } |
208 | |
209 | impl Pow<Z0> for $t { |
210 | type Output = $t; |
211 | #[inline] |
212 | fn powi(self, _: Z0) -> Self::Output { |
213 | 1 |
214 | } |
215 | } |
216 | |
217 | impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t { |
218 | type Output = $t; |
219 | #[inline] |
220 | fn powi(self, _: PInt<U>) -> Self::Output { |
221 | self.pow(U::to_u32()) |
222 | } |
223 | } |
224 | |
225 | impl_pow_i!($($tail),*); |
226 | ); |
227 | } |
228 | |
229 | impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); |
230 | #[cfg (feature = "i128" )] |
231 | impl_pow_i!(u128, i128); |
232 | |
233 | #[test ] |
234 | fn pow_test() { |
235 | use crate::consts::*; |
236 | let z0 = Z0::new(); |
237 | let p3 = P3::new(); |
238 | |
239 | let u0 = U0::new(); |
240 | let u3 = U3::new(); |
241 | let n3 = N3::new(); |
242 | |
243 | macro_rules! check { |
244 | ($x:ident) => { |
245 | assert_eq!($x.powi(z0), 1); |
246 | assert_eq!($x.powi(u0), 1); |
247 | |
248 | assert_eq!($x.powi(p3), $x * $x * $x); |
249 | assert_eq!($x.powi(u3), $x * $x * $x); |
250 | }; |
251 | ($x:ident, $f:ident) => { |
252 | assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON); |
253 | assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON); |
254 | |
255 | assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON); |
256 | assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON); |
257 | |
258 | if *$x == 0.0 { |
259 | assert!(<$f as Pow<N3>>::powi(*$x, n3).is_infinite()); |
260 | } else { |
261 | assert!( |
262 | (<$f as Pow<N3>>::powi(*$x, n3) - 1. / $x / $x / $x).abs() |
263 | < ::core::$f::EPSILON |
264 | ); |
265 | } |
266 | }; |
267 | } |
268 | |
269 | for x in &[0i8, -3, 2] { |
270 | check!(x); |
271 | } |
272 | for x in &[0u8, 1, 5] { |
273 | check!(x); |
274 | } |
275 | for x in &[0usize, 1, 5, 40] { |
276 | check!(x); |
277 | } |
278 | for x in &[0isize, 1, 2, -30, -22, 48] { |
279 | check!(x); |
280 | } |
281 | for x in &[0.0f32, 2.2, -3.5, 378.223] { |
282 | check!(x, f32); |
283 | } |
284 | for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] { |
285 | check!(x, f64); |
286 | } |
287 | } |
288 | |
289 | /// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to |
290 | /// the function |
291 | /// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp) |
292 | /// but for types. |
293 | /// |
294 | /// # Example |
295 | /// ```rust |
296 | /// use typenum::{Cmp, Ord, N3, P2, P5}; |
297 | /// use std::cmp::Ordering; |
298 | /// |
299 | /// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater); |
300 | /// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal); |
301 | /// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less); |
302 | pub trait Cmp<Rhs = Self> { |
303 | /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`. |
304 | type Output; |
305 | |
306 | #[doc (hidden)] |
307 | fn compare<IM: InternalMarker>(&self, _: &Rhs) -> Self::Output; |
308 | } |
309 | |
310 | /// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`. |
311 | pub trait Len { |
312 | /// The length as a type-level unsigned integer. |
313 | type Output: crate::Unsigned; |
314 | /// This function isn't used in this crate, but may be useful for others. |
315 | fn len(&self) -> Self::Output; |
316 | } |
317 | |
318 | /// Division as a partial function. This **type operator** performs division just as `Div`, but is |
319 | /// only defined when the result is an integer (i.e. there is no remainder). |
320 | pub trait PartialDiv<Rhs = Self> { |
321 | /// The type of the result of the division |
322 | type Output; |
323 | /// Method for performing the division |
324 | fn partial_div(self, _: Rhs) -> Self::Output; |
325 | } |
326 | |
327 | /// A **type operator** that returns the minimum of `Self` and `Rhs`. |
328 | pub trait Min<Rhs = Self> { |
329 | /// The type of the minimum of `Self` and `Rhs` |
330 | type Output; |
331 | /// Method returning the minimum |
332 | fn min(self, rhs: Rhs) -> Self::Output; |
333 | } |
334 | |
335 | /// A **type operator** that returns the maximum of `Self` and `Rhs`. |
336 | pub trait Max<Rhs = Self> { |
337 | /// The type of the maximum of `Self` and `Rhs` |
338 | type Output; |
339 | /// Method returning the maximum |
340 | fn max(self, rhs: Rhs) -> Self::Output; |
341 | } |
342 | |
343 | use crate::Compare; |
344 | |
345 | /// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`. |
346 | pub trait IsLess<Rhs = Self> { |
347 | /// The type representing either `True` or `False` |
348 | type Output: Bit; |
349 | /// Method returning `True` or `False`. |
350 | fn is_less(self, rhs: Rhs) -> Self::Output; |
351 | } |
352 | |
353 | use crate::private::IsLessPrivate; |
354 | impl<A, B> IsLess<B> for A |
355 | where |
356 | A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>, |
357 | { |
358 | type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output; |
359 | |
360 | #[inline ] |
361 | fn is_less(self, rhs: B) -> Self::Output { |
362 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
363 | self.is_less_private(rhs, lhs_cmp_rhs) |
364 | } |
365 | } |
366 | |
367 | /// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`. |
368 | pub trait IsEqual<Rhs = Self> { |
369 | /// The type representing either `True` or `False` |
370 | type Output: Bit; |
371 | /// Method returning `True` or `False`. |
372 | fn is_equal(self, rhs: Rhs) -> Self::Output; |
373 | } |
374 | |
375 | use crate::private::IsEqualPrivate; |
376 | impl<A, B> IsEqual<B> for A |
377 | where |
378 | A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>, |
379 | { |
380 | type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output; |
381 | |
382 | #[inline ] |
383 | fn is_equal(self, rhs: B) -> Self::Output { |
384 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
385 | self.is_equal_private(rhs, lhs_cmp_rhs) |
386 | } |
387 | } |
388 | |
389 | /// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`. |
390 | pub trait IsGreater<Rhs = Self> { |
391 | /// The type representing either `True` or `False` |
392 | type Output: Bit; |
393 | /// Method returning `True` or `False`. |
394 | fn is_greater(self, rhs: Rhs) -> Self::Output; |
395 | } |
396 | |
397 | use crate::private::IsGreaterPrivate; |
398 | impl<A, B> IsGreater<B> for A |
399 | where |
400 | A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>, |
401 | { |
402 | type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output; |
403 | |
404 | #[inline ] |
405 | fn is_greater(self, rhs: B) -> Self::Output { |
406 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
407 | self.is_greater_private(rhs, lhs_cmp_rhs) |
408 | } |
409 | } |
410 | |
411 | /// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`. |
412 | pub trait IsLessOrEqual<Rhs = Self> { |
413 | /// The type representing either `True` or `False` |
414 | type Output: Bit; |
415 | /// Method returning `True` or `False`. |
416 | fn is_less_or_equal(self, rhs: Rhs) -> Self::Output; |
417 | } |
418 | |
419 | use crate::private::IsLessOrEqualPrivate; |
420 | impl<A, B> IsLessOrEqual<B> for A |
421 | where |
422 | A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>, |
423 | { |
424 | type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output; |
425 | |
426 | #[inline ] |
427 | fn is_less_or_equal(self, rhs: B) -> Self::Output { |
428 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
429 | self.is_less_or_equal_private(rhs, lhs_cmp_rhs) |
430 | } |
431 | } |
432 | |
433 | /// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`. |
434 | pub trait IsNotEqual<Rhs = Self> { |
435 | /// The type representing either `True` or `False` |
436 | type Output: Bit; |
437 | /// Method returning `True` or `False`. |
438 | fn is_not_equal(self, rhs: Rhs) -> Self::Output; |
439 | } |
440 | |
441 | use crate::private::IsNotEqualPrivate; |
442 | impl<A, B> IsNotEqual<B> for A |
443 | where |
444 | A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>, |
445 | { |
446 | type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output; |
447 | |
448 | #[inline ] |
449 | fn is_not_equal(self, rhs: B) -> Self::Output { |
450 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
451 | self.is_not_equal_private(rhs, lhs_cmp_rhs) |
452 | } |
453 | } |
454 | |
455 | /// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`. |
456 | pub trait IsGreaterOrEqual<Rhs = Self> { |
457 | /// The type representing either `True` or `False` |
458 | type Output: Bit; |
459 | /// Method returning `True` or `False`. |
460 | fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output; |
461 | } |
462 | |
463 | use crate::private::IsGreaterOrEqualPrivate; |
464 | impl<A, B> IsGreaterOrEqual<B> for A |
465 | where |
466 | A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>, |
467 | { |
468 | type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output; |
469 | |
470 | #[inline ] |
471 | fn is_greater_or_equal(self, rhs: B) -> Self::Output { |
472 | let lhs_cmp_rhs: >::Output = self.compare::<Internal>(&rhs); |
473 | self.is_greater_or_equal_private(rhs, lhs_cmp_rhs) |
474 | } |
475 | } |
476 | |
477 | /** |
478 | A convenience macro for comparing type numbers. Use `op!` instead. |
479 | |
480 | Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple |
481 | `ident`, you must place a comma between it and the comparison sign. |
482 | |
483 | For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not |
484 | `cmp!(typenum::P5 > typenum::P3)`. |
485 | |
486 | The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`). |
487 | |
488 | # Example |
489 | ```rust |
490 | #[macro_use] extern crate typenum; |
491 | use typenum::consts::*; |
492 | use typenum::Bit; |
493 | |
494 | fn main() { |
495 | type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2))); |
496 | assert_eq!(Result::to_bool(), true); |
497 | } |
498 | ``` |
499 | */ |
500 | #[deprecated (since = "1.9.0" , note = "use the `op!` macro instead" )] |
501 | #[macro_export ] |
502 | macro_rules! cmp { |
503 | ($a:ident < $b:ty) => { |
504 | <$a as $crate::IsLess<$b>>::Output |
505 | }; |
506 | ($a:ty, < $b:ty) => { |
507 | <$a as $crate::IsLess<$b>>::Output |
508 | }; |
509 | |
510 | ($a:ident == $b:ty) => { |
511 | <$a as $crate::IsEqual<$b>>::Output |
512 | }; |
513 | ($a:ty, == $b:ty) => { |
514 | <$a as $crate::IsEqual<$b>>::Output |
515 | }; |
516 | |
517 | ($a:ident > $b:ty) => { |
518 | <$a as $crate::IsGreater<$b>>::Output |
519 | }; |
520 | ($a:ty, > $b:ty) => { |
521 | <$a as $crate::IsGreater<$b>>::Output |
522 | }; |
523 | |
524 | ($a:ident <= $b:ty) => { |
525 | <$a as $crate::IsLessOrEqual<$b>>::Output |
526 | }; |
527 | ($a:ty, <= $b:ty) => { |
528 | <$a as $crate::IsLessOrEqual<$b>>::Output |
529 | }; |
530 | |
531 | ($a:ident != $b:ty) => { |
532 | <$a as $crate::IsNotEqual<$b>>::Output |
533 | }; |
534 | ($a:ty, != $b:ty) => { |
535 | <$a as $crate::IsNotEqual<$b>>::Output |
536 | }; |
537 | |
538 | ($a:ident >= $b:ty) => { |
539 | <$a as $crate::IsGreaterOrEqual<$b>>::Output |
540 | }; |
541 | ($a:ty, >= $b:ty) => { |
542 | <$a as $crate::IsGreaterOrEqual<$b>>::Output |
543 | }; |
544 | } |
545 | |
546 | /// A **type operator** for taking the integer square root of `Self`. |
547 | /// |
548 | /// The integer square root of `n` is the largest integer `m` such |
549 | /// that `n >= m*m`. This definition is equivalent to truncating the |
550 | /// real-valued square root: `floor(real_sqrt(n))`. |
551 | pub trait SquareRoot { |
552 | /// The result of the integer square root. |
553 | type Output; |
554 | } |
555 | |
556 | /// A **type operator** for taking the integer binary logarithm of `Self`. |
557 | /// |
558 | /// The integer binary logarighm of `n` is the largest integer `m` such |
559 | /// that `n >= 2^m`. This definition is equivalent to truncating the |
560 | /// real-valued binary logarithm: `floor(log2(n))`. |
561 | pub trait Logarithm2 { |
562 | /// The result of the integer binary logarithm. |
563 | type Output; |
564 | } |
565 | |
566 | /// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`. |
567 | /// |
568 | /// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor |
569 | /// |
570 | /// # Example |
571 | /// |
572 | /// ```rust |
573 | /// use typenum::{Gcd, Unsigned, U12, U8}; |
574 | /// |
575 | /// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4); |
576 | /// ``` |
577 | pub trait Gcd<Rhs> { |
578 | /// The greatest common divisor. |
579 | type Output; |
580 | } |
581 | |
582 | /// A **type operator** for taking a concrete integer value from a type. |
583 | /// |
584 | /// It returns arbitrary integer value without explicitly specifying the |
585 | /// type. It is useful when you pass the values to methods that accept |
586 | /// distinct types without runtime casting. |
587 | pub trait ToInt<T> { |
588 | /// Method returning the concrete value for the type. |
589 | fn to_int() -> T; |
590 | /// The concrete value for the type. Can be used in `const` contexts. |
591 | const INT: T; |
592 | } |
593 | |