numera/number/integer/prime/
impl_traits.rs

1// numera::number::integer::prime::impl_traits
2//
3//!
4//
5// NOTE: chosen the is_prime for Prime8 & Prime16 because it's faster.
6
7use 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/* Prime8 */
25
26#[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    /// The largest 8-bit prime equals [`u8::MAX`] - 4.
54    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    /// Returns the next prime.
66    ///
67    /// # Examples
68    /// ```
69    /// use numera::all::{Countable, Number, Prime8};
70    /// # use numera::error::NumeraResult;
71    /// # fn main() -> NumeraResult<()> {
72    /// assert_eq![Prime8::from_inner_repr(2)?.next()?, Prime8::from_inner_repr(3)?];
73    /// assert_eq![Prime8::from_inner_repr(241)?.next()?, Prime8::from_inner_repr(251)?];
74    /// assert![Prime8::from_inner_repr(251)?.next().is_err()];
75    /// # Ok(()) }
76    /// ```
77    #[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    /// Returns the previous prime.
86    ///
87    /// # Examples
88    /// ```
89    /// use numera::all::{Countable, Number, Prime8};
90    /// # use numera::error::NumeraResult;
91    /// # fn main() -> NumeraResult<()> {
92    /// assert_eq![Prime8::from_inner_repr(3)?.previous()?, Prime8::from_inner_repr(2)?, ];
93    /// assert_eq![Prime8::from_inner_repr(251)?.previous()?, Prime8::from_inner_repr(241)?];
94    /// assert![Prime8::from_inner_repr(2)?.previous().is_err()];
95    /// # Ok(()) }
96    /// ```
97    #[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/* Prime16 */
184
185#[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    /// The largest 16-bit prime equals [`u16::MAX`] - 14.
213    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    /// Returns the next prime.
224    ///
225    /// # Examples
226    /// ```
227    /// use numera::all::{Countable, Number, Prime16};
228    /// # use numera::error::NumeraResult;
229    /// # fn main() -> NumeraResult<()> {
230    /// assert_eq![Prime16::from_inner_repr(5)?.next()?, Prime16::from_inner_repr(7)?];
231    /// assert_eq![Prime16::from_inner_repr(251)?.next()?, Prime16::from_inner_repr(257)?];
232    /// assert_eq![Prime16::from_inner_repr(257)?.next()?, Prime16::from_inner_repr(263)?];
233    /// assert_eq![Prime16::from_inner_repr(65_519)?.next()?, Prime16::from_inner_repr(65_521)?];
234    /// assert![Prime16::from_inner_repr(65_521)?.next().is_err()];
235    /// # Ok(()) }
236    /// ```
237    #[inline]
238    fn next(&self) -> NumeraResult<Self> {
239        let nth = self.pi();
240        match nth {
241            // can't be 0
242            1..=53 => Ok(Prime16(u16::from(PRIMES_U8[nth]))),
243            54..=6_541 => Ok(Prime16(PRIMES_U16[nth - 54])),
244            // otherwise it can only be 6_542
245            _ => Err(IntegerErrors::Overflow.into()),
246        }
247
248        // ALTERNATIVE:
249        // if self.0 == 65_521 { Err(IntegerErrors::Overflow.into()) } else {
250        //     let sieve = Sieve::new(min(self.0.saturating_add(1000), u16::MAX) as usize);
251        //     let nth = sieve.prime_pi(self.0 as usize);
252        //     let next_prime = sieve.nth_prime(nth + 1);
253        //     Ok(Prime16(next_prime.try_into().unwrap()))
254        // }
255    }
256
257    /// Returns the previous prime.
258    ///
259    /// # Examples
260    /// ```
261    /// use numera::all::{Countable, Number, Prime16};
262    /// # use numera::error::NumeraResult;
263    /// # fn main() -> NumeraResult<()> {
264    /// assert_eq![Prime16::from_inner_repr(7)?.previous()?, Prime16::from_inner_repr(5)?];
265    /// assert_eq![Prime16::from_inner_repr(251)?.previous()?, Prime16::from_inner_repr(241)?];
266    /// assert_eq![Prime16::from_inner_repr(257)?.previous()?, Prime16::from_inner_repr(251)?];
267    /// assert_eq![Prime16::from_inner_repr(65_521)?.previous()?, Prime16::from_inner_repr(65_519)?];
268    /// assert![Prime16::from_inner_repr(2)?.previous().is_err()];
269    /// # Ok(()) }
270    /// ```
271    #[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            // otherwise it can only be 1
278            _ => Err(IntegerErrors::Underflow.into()),
279        }
280
281        // ALTERNATIVE:
282        // if self.0 == 2 { Err(IntegerErrors::Underflow.into()) } else {
283        //     let sieve = Sieve::new(min(self.0.saturating_add(1000), u16::MAX) as usize);
284        //     let nth = sieve.prime_pi(self.0 as usize);
285        //     let prev_prime = sieve.nth_prime(nth - 1);
286        //     Ok(Prime16(prev_prime.try_into().unwrap()))
287        // }
288    }
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/* Prime32 */
368
369#[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    /// The largest 32-bit prime equals [`u32::MAX`] - 4.
397    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// TODO:IMPROVE for no-std
408#[rustfmt::skip]
409#[cfg(not(feature = "std"))]
410impl Countable for Prime32 {
411    /// Not implemented for no-std.
412    fn next(&self) -> NumeraResult<Self> { Err(crate::all::NumeraErrors::NotImplemented) }
413    /// Not implemented for no-std.
414    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    /// Returns the next prime.
420    ///
421    /// Note that this operation can be slow for high values.
422    ///
423    /// # Examples
424    /// ```
425    /// use numera::all::{Countable, Number, Prime32};
426    /// # use numera::error::NumeraResult;
427    /// # fn main() -> NumeraResult<()> {
428    /// assert_eq![Prime32::from_inner_repr(5)?.next()?, Prime32::from_inner_repr(7)?];
429    /// assert_eq![Prime32::from_inner_repr(251)?.next()?, Prime32::from_inner_repr(257)?];
430    /// assert_eq![Prime32::from_inner_repr(65_521)?.next()?, Prime32::from_inner_repr(65_537)?];
431    /// assert_eq![Prime32::from_inner_repr(50_000_017)?.next()?, Prime32::from_inner_repr(50_000_021)?];
432    /// // assert![Prime32::from_inner_repr(4_294_967_291)?.next().is_err()]; // SLOW
433    /// # Ok(()) }
434    /// ```
435    #[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    /// Returns the previous prime.
447    ///
448    /// Note that this operation can be slow for high values.
449    ///
450    /// # Examples
451    /// ```
452    /// use numera::all::{Countable, Number, Prime32};
453    /// # use numera::error::NumeraResult;
454    /// # fn main() -> NumeraResult<()> {
455    /// assert_eq![Prime32::from_inner_repr(7)?.previous()?, Prime32::from_inner_repr(5)?];
456    /// assert_eq![Prime32::from_inner_repr(257)?.previous()?, Prime32::from_inner_repr(251)?];
457    /// assert_eq![Prime32::from_inner_repr(65_537)?.previous()?, Prime32::from_inner_repr(65_521)?];
458    /// assert_eq![Prime32::from_inner_repr(50_000_021)?.previous()?, Prime32::from_inner_repr(50_000_017)?];
459    /// // assert![Prime32::from_inner_repr(4_294_967_291)?.previous().is_err()]; // SLOW
460    /// # Ok(()) }
461    /// ```
462    #[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/* Prime64 */
572
573#[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    /// The largest 64-bit prime equals [`u64::MAX`] - 58.
601    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// // TODO
612// #[rustfmt::skip]
613// #[cfg(not(feature = "std"))]
614// impl Countable for Prime64 {
615// }
616// #[cfg(feature = "std")]
617// #[cfg_attr(feature = "nightly", doc(cfg(feature = "std")))]
618// impl Countable for Prime64 {
619// }
620
621#[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        // IMPROVE
661        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/* Prime128 */
719
720#[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    /// The largest 128-bit prime equals [`u128::MAX`] - 158.
748    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// // TODO
759// #[rustfmt::skip]
760// #[cfg(not(feature = "std"))]
761// impl Countable for Prime128 {
762// }
763// #[cfg(feature = "std")]
764// #[cfg_attr(feature = "nightly", doc(cfg(feature = "std")))]
765// impl Countable for Prime128 {
766// }
767
768#[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}