numera/number/integer/prime/
impl_traits.rs1use super::{
8 data::{PRIMES_U16, PRIMES_U8},
9 is_prime, Prime128, Prime16, Prime32, Prime64, Prime8,
10};
11use crate::{
12 error::{IntegerErrors, NumeraResult},
13 number::traits::{
14 Bound, ConstLowerBounded, ConstUpperBounded, Count, Countable, Ident, LowerBounded,
15 NonNegative, NonOne, NonZero, Number, Positive, Sign, UpperBounded,
16 },
17};
18
19#[cfg(feature = "std")]
20use {
21 crate::all::is_prime_sieve, core::cmp::min, devela::convert::az::CheckedAs, primal_sieve::Sieve,
22};
23
24#[rustfmt::skip]
27impl Bound for Prime8 {
28 #[inline]
29 fn is_lower_bounded(&self) -> bool { true }
30 #[inline]
31 fn is_upper_bounded(&self) -> bool { true }
32 #[inline]
33 fn lower_bound(&self) -> Option<Self> { Some(Prime8::MIN) }
34 #[inline]
35 fn upper_bound(&self) -> Option<Self> { Some(Prime8::MAX) }
36}
37impl LowerBounded for Prime8 {
38 #[inline]
39 fn new_min() -> Self {
40 Prime8::MIN
41 }
42}
43impl UpperBounded for Prime8 {
44 #[inline]
45 fn new_max() -> Self {
46 Prime8::MAX
47 }
48}
49impl ConstLowerBounded for Prime8 {
50 const MIN: Self = Prime8(2);
51}
52impl ConstUpperBounded for Prime8 {
53 const MAX: Self = Prime8(251);
55}
56
57impl Count for Prime8 {
58 #[inline]
59 fn is_countable(&self) -> bool {
60 true
61 }
62}
63
64impl Countable for Prime8 {
65 #[inline]
78 fn next(&self) -> NumeraResult<Self> {
79 let nth = self.pi();
80 match nth {
81 54 => Err(IntegerErrors::Overflow.into()),
82 _ => Ok(Prime8(PRIMES_U8[nth])),
83 }
84 }
85 #[inline]
98 fn previous(&self) -> NumeraResult<Self> {
99 let nth = self.pi();
100 match nth {
101 1 => Err(IntegerErrors::Underflow.into()),
102 _ => Ok(Prime8(PRIMES_U8[nth - 2])),
103 }
104 }
105}
106
107#[rustfmt::skip]
108impl Ident for Prime8 {
109 #[inline]
110 fn can_zero(&self) -> bool { false }
111 #[inline]
112 fn can_one(&self) -> bool { false }
113 #[inline]
114 fn can_neg_one(&self) -> bool { false }
115 #[inline]
116 fn is_zero(&self) -> bool { false }
117 #[inline]
118 fn is_one(&self) -> bool { false }
119 #[inline]
120 fn is_neg_one(&self) -> bool { false }
121}
122impl NonZero for Prime8 {}
123impl NonOne for Prime8 {}
124
125#[rustfmt::skip]
126impl Sign for Prime8 {
127 #[inline]
128 fn can_positive(&self) -> bool { true }
129 #[inline]
130 fn can_negative(&self) -> bool { false }
131 #[inline]
132 fn is_positive(&self) -> bool { true }
133 #[inline]
134 fn is_negative(&self) -> bool { false }
135}
136impl NonNegative for Prime8 {}
137impl Positive for Prime8 {}
138
139impl Number for Prime8 {
140 type InnerRepr = u8;
141 type InnermostRepr = u8;
142
143 #[inline]
144 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
145 if is_prime(value.into()) {
146 Ok(Self(value))
147 } else {
148 Err(IntegerErrors::NotPrime.into())
149 }
150 }
151 #[inline]
152 #[cfg(not(feature = "safe"))]
153 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
154 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
155 Self(value)
156 }
157
158 #[inline]
159 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
160 if is_prime(value.into()) {
161 Ok(Self(value))
162 } else {
163 Err(IntegerErrors::NotPrime.into())
164 }
165 }
166 #[inline]
167 #[cfg(not(feature = "safe"))]
168 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
169 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
170 Self(value)
171 }
172
173 #[inline]
174 fn into_inner_repr(self) -> Self::InnerRepr {
175 self.0
176 }
177 #[inline]
178 fn into_innermost_repr(self) -> Self::InnermostRepr {
179 self.0
180 }
181}
182
183#[rustfmt::skip]
186impl Bound for Prime16 {
187 #[inline]
188 fn is_lower_bounded(&self) -> bool { true }
189 #[inline]
190 fn is_upper_bounded(&self) -> bool { true }
191 #[inline]
192 fn lower_bound(&self) -> Option<Self> { Some(Prime16::MIN) }
193 #[inline]
194 fn upper_bound(&self) -> Option<Self> { Some(Prime16::MAX) }
195}
196impl LowerBounded for Prime16 {
197 #[inline]
198 fn new_min() -> Self {
199 Prime16::MIN
200 }
201}
202impl UpperBounded for Prime16 {
203 #[inline]
204 fn new_max() -> Self {
205 Prime16::MAX
206 }
207}
208impl ConstLowerBounded for Prime16 {
209 const MIN: Self = Prime16(2);
210}
211impl ConstUpperBounded for Prime16 {
212 const MAX: Self = Prime16(65_521);
214}
215
216impl Count for Prime16 {
217 #[inline]
218 fn is_countable(&self) -> bool {
219 true
220 }
221}
222impl Countable for Prime16 {
223 #[inline]
238 fn next(&self) -> NumeraResult<Self> {
239 let nth = self.pi();
240 match nth {
241 1..=53 => Ok(Prime16(u16::from(PRIMES_U8[nth]))),
243 54..=6_541 => Ok(Prime16(PRIMES_U16[nth - 54])),
244 _ => Err(IntegerErrors::Overflow.into()),
246 }
247
248 }
256
257 #[inline]
272 fn previous(&self) -> NumeraResult<Self> {
273 let nth = self.pi();
274 match nth {
275 2..=55 => Ok(Prime16(u16::from(PRIMES_U8[nth - 2]))),
276 56..=6_542 => Ok(Prime16(PRIMES_U16[nth - 54 - 2])),
277 _ => Err(IntegerErrors::Underflow.into()),
279 }
280
281 }
289}
290
291#[rustfmt::skip]
292impl Ident for Prime16 {
293 #[inline]
294 fn can_zero(&self) -> bool { false }
295 #[inline]
296 fn can_one(&self) -> bool { false }
297 #[inline]
298 fn can_neg_one(&self) -> bool { false }
299 #[inline]
300 fn is_zero(&self) -> bool { false }
301 #[inline]
302 fn is_one(&self) -> bool { false }
303 #[inline]
304 fn is_neg_one(&self) -> bool { false }
305}
306impl NonZero for Prime16 {}
307impl NonOne for Prime16 {}
308
309#[rustfmt::skip]
310impl Sign for Prime16 {
311 #[inline]
312 fn can_positive(&self) -> bool { true }
313 #[inline]
314 fn can_negative(&self) -> bool { false }
315 #[inline]
316 fn is_positive(&self) -> bool { true }
317 #[inline]
318 fn is_negative(&self) -> bool { false }
319}
320impl NonNegative for Prime16 {}
321impl Positive for Prime16 {}
322
323impl Number for Prime16 {
324 type InnerRepr = u16;
325 type InnermostRepr = u16;
326
327 #[inline]
328 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
329 if is_prime(value.into()) {
330 Ok(Self(value))
331 } else {
332 Err(IntegerErrors::NotPrime.into())
333 }
334 }
335 #[inline]
336 #[cfg(not(feature = "safe"))]
337 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
338 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
339 Self(value)
340 }
341
342 #[inline]
343 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
344 if is_prime(value.into()) {
345 Ok(Self(value))
346 } else {
347 Err(IntegerErrors::NotPrime.into())
348 }
349 }
350 #[inline]
351 #[cfg(not(feature = "safe"))]
352 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
353 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
354 Self(value)
355 }
356
357 #[inline]
358 fn into_inner_repr(self) -> Self::InnerRepr {
359 self.0
360 }
361 #[inline]
362 fn into_innermost_repr(self) -> Self::InnermostRepr {
363 self.0
364 }
365}
366
367#[rustfmt::skip]
370impl Bound for Prime32 {
371 #[inline]
372 fn is_lower_bounded(&self) -> bool { true }
373 #[inline]
374 fn is_upper_bounded(&self) -> bool { true }
375 #[inline]
376 fn lower_bound(&self) -> Option<Self> { Some(Prime32::MIN) }
377 #[inline]
378 fn upper_bound(&self) -> Option<Self> { Some(Prime32::MAX) }
379}
380impl LowerBounded for Prime32 {
381 #[inline]
382 fn new_min() -> Self {
383 Prime32::MIN
384 }
385}
386impl UpperBounded for Prime32 {
387 #[inline]
388 fn new_max() -> Self {
389 Prime32::MAX
390 }
391}
392impl ConstLowerBounded for Prime32 {
393 const MIN: Self = Prime32(2);
394}
395impl ConstUpperBounded for Prime32 {
396 const MAX: Self = Prime32(4_294_967_291);
398}
399
400impl Count for Prime32 {
401 #[inline]
402 fn is_countable(&self) -> bool {
403 true
404 }
405}
406
407#[rustfmt::skip]
409#[cfg(not(feature = "std"))]
410impl Countable for Prime32 {
411 fn next(&self) -> NumeraResult<Self> { Err(crate::all::NumeraErrors::NotImplemented) }
413 fn previous(&self) -> NumeraResult<Self> { Err(crate::all::NumeraErrors::NotImplemented) }
415}
416#[cfg(feature = "std")]
417#[cfg_attr(feature = "nightly", doc(cfg(feature = "std")))]
418impl Countable for Prime32 {
419 #[inline]
436 fn next(&self) -> NumeraResult<Self> {
437 if self.0 == 4_294_967_291 {
438 Err(IntegerErrors::Overflow.into())
439 } else {
440 let sieve = Sieve::new(min(self.0.saturating_add(1000), u32::MAX) as usize);
441 let nth = sieve.prime_pi(self.0 as usize);
442 let next_prime = sieve.nth_prime(nth + 1);
443 Ok(Prime32(next_prime.try_into().unwrap()))
444 }
445 }
446 #[inline]
463 fn previous(&self) -> NumeraResult<Self> {
464 if self.0 == 2 {
465 Err(IntegerErrors::Underflow.into())
466 } else {
467 let sieve = Sieve::new(min(self.0.saturating_add(1000), u32::MAX) as usize);
468 let nth = sieve.prime_pi(self.0 as usize);
469 let prev_prime = sieve.nth_prime(nth - 1);
470 Ok(Prime32(prev_prime.try_into().unwrap()))
471 }
472 }
473}
474
475#[rustfmt::skip]
476impl Ident for Prime32 {
477 #[inline]
478 fn can_zero(&self) -> bool { false }
479 #[inline]
480 fn can_one(&self) -> bool { false }
481 #[inline]
482 fn can_neg_one(&self) -> bool { false }
483 #[inline]
484 fn is_zero(&self) -> bool { false }
485 #[inline]
486 fn is_one(&self) -> bool { false }
487 #[inline]
488 fn is_neg_one(&self) -> bool { false }
489}
490impl NonZero for Prime32 {}
491impl NonOne for Prime32 {}
492
493#[rustfmt::skip]
494impl Sign for Prime32 {
495 #[inline]
496 fn can_positive(&self) -> bool { true }
497 #[inline]
498 fn can_negative(&self) -> bool { false }
499 #[inline]
500 fn is_positive(&self) -> bool { true }
501 #[inline]
502 fn is_negative(&self) -> bool { false }
503}
504impl NonNegative for Prime32 {}
505impl Positive for Prime32 {}
506
507impl Number for Prime32 {
508 type InnerRepr = u32;
509 type InnermostRepr = u32;
510
511 #[inline]
512 #[cfg(not(feature = "std"))]
513 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
514 if is_prime(value) {
515 Ok(Self(value))
516 } else {
517 Err(IntegerErrors::NotPrime.into())
518 }
519 }
520 #[inline]
521 #[cfg(feature = "std")]
522 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
523 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
524 Ok(Self(value))
525 } else {
526 Err(IntegerErrors::NotPrime.into())
527 }
528 }
529 #[inline]
530 #[cfg(not(feature = "safe"))]
531 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
532 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
533 Self(value)
534 }
535
536 #[inline]
537 #[cfg(not(feature = "std"))]
538 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
539 if is_prime(value) {
540 Ok(Self(value))
541 } else {
542 Err(IntegerErrors::NotPrime.into())
543 }
544 }
545 #[inline]
546 #[cfg(feature = "std")]
547 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
548 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
549 Ok(Self(value))
550 } else {
551 Err(IntegerErrors::NotPrime.into())
552 }
553 }
554 #[inline]
555 #[cfg(not(feature = "safe"))]
556 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
557 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
558 Self(value)
559 }
560
561 #[inline]
562 fn into_inner_repr(self) -> Self::InnerRepr {
563 self.0
564 }
565 #[inline]
566 fn into_innermost_repr(self) -> Self::InnermostRepr {
567 self.0
568 }
569}
570
571#[rustfmt::skip]
574impl Bound for Prime64 {
575 #[inline]
576 fn is_lower_bounded(&self) -> bool { true }
577 #[inline]
578 fn is_upper_bounded(&self) -> bool { true }
579 #[inline]
580 fn lower_bound(&self) -> Option<Self> { Some(Prime64::MIN) }
581 #[inline]
582 fn upper_bound(&self) -> Option<Self> { Some(Prime64::MAX) }
583}
584impl LowerBounded for Prime64 {
585 #[inline]
586 fn new_min() -> Self {
587 Prime64::MIN
588 }
589}
590impl UpperBounded for Prime64 {
591 #[inline]
592 fn new_max() -> Self {
593 Prime64::MAX
594 }
595}
596impl ConstLowerBounded for Prime64 {
597 const MIN: Self = Prime64(2);
598}
599impl ConstUpperBounded for Prime64 {
600 const MAX: Self = Prime64(18_446_744_073_709_551_557);
602}
603
604impl Count for Prime64 {
605 #[inline]
606 fn is_countable(&self) -> bool {
607 true
608 }
609}
610
611#[rustfmt::skip]
622impl Ident for Prime64 {
623 #[inline]
624 fn can_zero(&self) -> bool { false }
625 #[inline]
626 fn can_one(&self) -> bool { false }
627 #[inline]
628 fn can_neg_one(&self) -> bool { false }
629 #[inline]
630 fn is_zero(&self) -> bool { false }
631 #[inline]
632 fn is_one(&self) -> bool { false }
633 #[inline]
634 fn is_neg_one(&self) -> bool { false }
635}
636impl NonZero for Prime64 {}
637impl NonOne for Prime64 {}
638
639#[rustfmt::skip]
640impl Sign for Prime64 {
641 #[inline]
642 fn can_positive(&self) -> bool { true }
643 #[inline]
644 fn can_negative(&self) -> bool { false }
645 #[inline]
646 fn is_positive(&self) -> bool { true }
647 #[inline]
648 fn is_negative(&self) -> bool { false }
649}
650impl NonNegative for Prime64 {}
651impl Positive for Prime64 {}
652
653impl Number for Prime64 {
654 type InnerRepr = u64;
655 type InnermostRepr = u64;
656
657 #[inline]
658 #[cfg(not(feature = "std"))]
659 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
660 if is_prime(value.try_into()?) {
662 Ok(Prime64(value))
663 } else {
664 Err(IntegerErrors::NotPrime.into())
665 }
666 }
667 #[inline]
668 #[cfg(feature = "std")]
669 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
670 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
671 Ok(Prime64(value))
672 } else {
673 Err(IntegerErrors::NotPrime.into())
674 }
675 }
676 #[inline]
677 #[cfg(not(feature = "safe"))]
678 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
679 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
680 Self(value)
681 }
682
683 #[inline]
684 #[cfg(not(feature = "std"))]
685 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
686 if is_prime(value.try_into()?) {
687 Ok(Self(value))
688 } else {
689 Err(IntegerErrors::NotPrime.into())
690 }
691 }
692 #[inline]
693 #[cfg(feature = "std")]
694 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
695 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
696 Ok(Self(value))
697 } else {
698 Err(IntegerErrors::NotPrime.into())
699 }
700 }
701 #[inline]
702 #[cfg(not(feature = "safe"))]
703 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
704 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
705 Self(value)
706 }
707
708 #[inline]
709 fn into_inner_repr(self) -> Self::InnerRepr {
710 self.0
711 }
712 #[inline]
713 fn into_innermost_repr(self) -> Self::InnermostRepr {
714 self.0
715 }
716}
717
718#[rustfmt::skip]
721impl Bound for Prime128 {
722 #[inline]
723 fn is_lower_bounded(&self) -> bool { true }
724 #[inline]
725 fn is_upper_bounded(&self) -> bool { true }
726 #[inline]
727 fn lower_bound(&self) -> Option<Self> { Some(Prime128::MIN) }
728 #[inline]
729 fn upper_bound(&self) -> Option<Self> { Some(Prime128::MAX) }
730}
731impl LowerBounded for Prime128 {
732 #[inline]
733 fn new_min() -> Self {
734 Prime128::MIN
735 }
736}
737impl UpperBounded for Prime128 {
738 #[inline]
739 fn new_max() -> Self {
740 Prime128::MAX
741 }
742}
743impl ConstLowerBounded for Prime128 {
744 const MIN: Self = Prime128(2);
745}
746impl ConstUpperBounded for Prime128 {
747 const MAX: Self = Prime128(340_282_366_920_938_463_463_374_607_431_768_211_297);
749}
750
751impl Count for Prime128 {
752 #[inline]
753 fn is_countable(&self) -> bool {
754 true
755 }
756}
757
758#[rustfmt::skip]
769impl Ident for Prime128 {
770 #[inline]
771 fn can_zero(&self) -> bool { false }
772 #[inline]
773 fn can_one(&self) -> bool { false }
774 #[inline]
775 fn can_neg_one(&self) -> bool { false }
776 #[inline]
777 fn is_zero(&self) -> bool { false }
778 #[inline]
779 fn is_one(&self) -> bool { false }
780 #[inline]
781 fn is_neg_one(&self) -> bool { false }
782}
783impl NonZero for Prime128 {}
784impl NonOne for Prime128 {}
785
786#[rustfmt::skip]
787impl Sign for Prime128 {
788 #[inline]
789 fn can_positive(&self) -> bool { true }
790 #[inline]
791 fn can_negative(&self) -> bool { false }
792 #[inline]
793 fn is_positive(&self) -> bool { true }
794 #[inline]
795 fn is_negative(&self) -> bool { false }
796}
797impl NonNegative for Prime128 {}
798impl Positive for Prime128 {}
799
800impl Number for Prime128 {
801 type InnerRepr = u128;
802 type InnermostRepr = u128;
803
804 #[inline]
805 #[cfg(not(feature = "std"))]
806 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
807 if is_prime(value.try_into()?) {
808 Ok(Prime128(value))
809 } else {
810 Err(IntegerErrors::NotPrime.into())
811 }
812 }
813 #[inline]
814 #[cfg(feature = "std")]
815 fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
816 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
817 Ok(Prime128(value))
818 } else {
819 Err(IntegerErrors::NotPrime.into())
820 }
821 }
822 #[inline]
823 #[cfg(not(feature = "safe"))]
824 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
825 unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
826 Self(value)
827 }
828
829 #[inline]
830 #[cfg(not(feature = "std"))]
831 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
832 if is_prime(value.try_into()?) {
833 Ok(Self(value))
834 } else {
835 Err(IntegerErrors::NotPrime.into())
836 }
837 }
838 #[inline]
839 #[cfg(feature = "std")]
840 fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
841 if is_prime_sieve(value.checked_as::<usize>().ok_or(IntegerErrors::Overflow)?) {
842 Ok(Self(value))
843 } else {
844 Err(IntegerErrors::NotPrime.into())
845 }
846 }
847 #[inline]
848 #[cfg(not(feature = "safe"))]
849 #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
850 unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
851 Self(value)
852 }
853
854 #[inline]
855 fn into_inner_repr(self) -> Self::InnerRepr {
856 self.0
857 }
858 #[inline]
859 fn into_innermost_repr(self) -> Self::InnermostRepr {
860 self.0
861 }
862}