jiff/util/
rangeint.rs

1// We squash dead_code warnings because we define all of our methods for all
2// primitive integer types, even though we don't use each method at least once
3// on each of the integer types. It would really just be too annoying to do
4// anything different. With that said, it is very likely that there is some
5// actual dead code below that we're missing because we squash the warning.
6#![allow(dead_code, non_snake_case, non_camel_case_types)]
7
8use core::{
9    cmp::Ordering,
10    ops::{
11        Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign,
12        Sub, SubAssign,
13    },
14};
15
16use crate::{error::Error, util::t::Constant};
17
18macro_rules! define_ranged {
19    (
20        $name:ident,
21        $repr:ty,
22        smaller { $($smaller_name:ident $smaller_repr:ty),* },
23        bigger { $($bigger_name:ident $bigger_repr:ty),* }
24    ) => {
25        #[derive(Clone, Copy, Hash)]
26        pub(crate) struct $name<const MIN: i128, const MAX: i128> {
27            /// The actual value of the integer.
28            ///
29            /// Callers should not access this directly. There are some very
30            /// rare cases where algorithms are too difficult to express on
31            /// ranged integers, and it's useful to be able to reach inside and
32            /// access the raw value directly. (For example, the conversions
33            /// between Unix epoch day and Gregorian date.)
34            pub(crate) val: $repr,
35            /// The minimum possible value computed so far.
36            ///
37            /// This value is only present when `debug_assertions` are enabled.
38            /// In that case, it is used to ensure the minimum possible value
39            /// when the integer is actually observed (or converted) is still
40            /// within the legal range.
41            ///
42            /// Callers should not access this directly. There are some very
43            /// rare cases where algorithms are too difficult to express on
44            /// ranged integers, and it's useful to be able to reach inside and
45            /// access the raw value directly. (For example, the conversions
46            /// between Unix epoch day and Gregorian date.)
47            #[cfg(debug_assertions)]
48            pub(crate) min: $repr,
49            /// The maximum possible value computed so far.
50            ///
51            /// This value is only present when `debug_assertions` are enabled.
52            /// In that case, it is used to ensure the maximum possible value
53            /// when the integer is actually observed (or converted) is still
54            /// within the legal range.
55            ///
56            /// Callers should not access this directly. There are some very
57            /// rare cases where algorithms are too difficult to express on
58            /// ranged integers, and it's useful to be able to reach inside and
59            /// access the raw value directly. (For example, the conversions
60            /// between Unix epoch day and Gregorian date.)
61            #[cfg(debug_assertions)]
62            pub(crate) max: $repr,
63        }
64
65        impl<const MIN: i128, const MAX: i128> $name<MIN, MAX> {
66            /// These are the absolute min/max values for the integer type
67            /// being used.
68            const PRIMITIVE_MIN: i128 = <$repr>::MIN as i128;
69            const PRIMITIVE_MAX: i128 = <$repr>::MAX as i128;
70
71            /// When true, this range integer has bounds precisely equivalent
72            /// to its underlying primitive representation.
73            const IS_PRIMITIVE: bool = Self::MIN_REPR == <$repr>::MIN
74                && Self::MAX_REPR == <$repr>::MAX;
75
76            /// The min/max values as given by our type parameters.
77            pub(crate) const MIN: i128 = MIN;
78            pub(crate) const MAX: i128 = MAX;
79
80            /// The number of distinct elements in this type's range.
81            pub(crate) const LEN: i128 = {
82                assert!(Self::PRIMITIVE_MIN < Self::PRIMITIVE_MAX);
83                MAX - MIN + 1
84            };
85
86            /// The min/max values of this type, represented in their
87            /// primitive form for easy comparisons with incoming values.
88            pub(crate) const MIN_REPR: $repr = {
89                assert!(
90                    Self::PRIMITIVE_MIN <= MIN && MIN <= Self::PRIMITIVE_MAX
91                );
92                MIN as $repr
93            };
94            pub(crate) const MAX_REPR: $repr = {
95                assert!(
96                    Self::PRIMITIVE_MIN <= MAX && MAX <= Self::PRIMITIVE_MAX
97                );
98                MAX as $repr
99            };
100
101            /// The min/max values of this type as a ranged type.
102            pub(crate) const MIN_SELF: Self =
103                Self::new_unchecked(Self::MIN_REPR);
104            pub(crate) const MAX_SELF: Self =
105                Self::new_unchecked(Self::MAX_REPR);
106
107            /// The min/max values of this type as a constant.
108            pub(crate) const MIN_CONST: Constant =
109                Constant(Self::MIN_REPR as i64);
110            pub(crate) const MAX_CONST: Constant =
111                Constant(Self::MAX_REPR as i64);
112
113            #[inline]
114            pub(crate) fn error(
115                what: &'static str,
116                given: $repr,
117            ) -> Error {
118                Error::range(what, given, Self::MIN_REPR, Self::MAX_REPR)
119            }
120
121            #[inline]
122            pub(crate) fn new(val: impl TryInto<$repr>) -> Option<Self> {
123                let val = val.try_into().ok()?;
124                if !Self::contains(val) {
125                    return None;
126                }
127                #[cfg(not(debug_assertions))]
128                {
129                    Some(Self { val })
130                }
131                #[cfg(debug_assertions)]
132                {
133                    Some(Self {
134                        val,
135                        min: Self::MIN_REPR,
136                        max: Self::MAX_REPR,
137                    })
138                }
139            }
140
141            #[inline]
142            pub(crate) fn try_new(
143                what: &'static str,
144                val: impl Into<i64>,
145            ) -> Result<Self, Error> {
146                let val = val.into();
147                #[allow(irrefutable_let_patterns)]
148                let Ok(val) = <$repr>::try_from(val) else {
149                    return Err(Error::range(
150                        what,
151                        val,
152                        Self::MIN_REPR,
153                        Self::MAX_REPR,
154                    ));
155                };
156                Self::new(val).ok_or_else(|| Self::error(what, val))
157            }
158
159            #[inline]
160            pub(crate) fn try_new128(
161                what: &'static str,
162                val: impl Into<i128>,
163            ) -> Result<Self, Error> {
164                let val = val.into();
165                #[allow(irrefutable_let_patterns)]
166                let Ok(val) = <$repr>::try_from(val) else {
167                    return Err(Error::range(
168                        what,
169                        val,
170                        Self::MIN_REPR,
171                        Self::MAX_REPR,
172                    ));
173                };
174                Self::new(val).ok_or_else(|| Self::error(what, val))
175            }
176
177            #[inline]
178            pub(crate) fn constrain(val: impl Into<$repr>) -> Self {
179                let val = val.into().clamp(Self::MIN_REPR, Self::MAX_REPR);
180                Self::new_unchecked(val)
181            }
182
183            #[inline]
184            pub(crate) const fn new_unchecked(val: $repr) -> Self {
185                #[cfg(not(debug_assertions))]
186                {
187                    Self { val }
188                }
189                #[cfg(debug_assertions)]
190                {
191                    assert!(Self::contains(val), "val is not in range");
192                    Self { val, min: Self::MIN_REPR, max: Self::MAX_REPR }
193                }
194            }
195
196            #[inline]
197            pub(crate) const fn N<const VAL: $repr>() -> Self {
198                #[cfg(not(debug_assertions))]
199                {
200                    Self { val: VAL }
201                }
202                #[cfg(debug_assertions)]
203                {
204                    Self { val: VAL, min: VAL, max: VAL }
205                }
206            }
207
208            #[inline]
209            pub(crate) const fn N128<const VAL: i128>() -> Self {
210                #[cfg(not(debug_assertions))]
211                {
212                    Self { val: VAL as $repr }
213                }
214                #[cfg(debug_assertions)]
215                {
216                    if !(MIN <= VAL && VAL <= MAX) {
217                        panic!("constant out of range");
218                    }
219                    let val = VAL as $repr;
220                    Self { val, min: val, max: val }
221                }
222            }
223
224            #[inline]
225            pub(crate) const fn V<
226                const VAL: $repr,
227                const START: $repr,
228                const END: $repr,
229            >() -> Self {
230                #[cfg(not(debug_assertions))]
231                {
232                    Self { val: VAL }
233                }
234                #[cfg(debug_assertions)]
235                {
236                    Self { val: VAL, min: START, max: END }
237                }
238            }
239
240            #[inline]
241            pub(crate) const fn contains(val: $repr) -> bool {
242                Self::MIN_REPR <= val && val <= Self::MAX_REPR
243            }
244
245            #[inline]
246            pub(crate) fn vary<
247                const N: usize,
248                const MIN2: i128,
249                const MAX2: i128,
250            >(
251                numbers: [Self; N],
252                with: impl Fn([Self; N]) -> $name<MIN2, MAX2>,
253            ) -> $name<MIN2, MAX2> {
254                let [result] =
255                    Self::vary_many(numbers, |numbers| [with(numbers)]);
256                result
257            }
258
259            #[inline]
260            pub(crate) fn vary_many<
261                const N: usize,
262                const M: usize,
263                const MIN2: i128,
264                const MAX2: i128,
265            >(
266                numbers: [Self; N],
267                with: impl Fn([Self; N]) -> [$name<MIN2, MAX2>; M],
268            ) -> [$name<MIN2, MAX2>; M] {
269                #[cfg(not(debug_assertions))]
270                {
271                    with(numbers)
272                }
273                #[cfg(debug_assertions)]
274                {
275                    let vals = with(numbers);
276                    let mins = with(numbers.map(|n| Self {
277                        val: n.min,
278                        min: n.min,
279                        max: n.max,
280                    }));
281                    let maxs = with(numbers.map(|n| Self {
282                        val: n.max,
283                        min: n.min,
284                        max: n.max,
285                    }));
286                    let mut result = [$name::MIN_SELF; M];
287                    let it = vals.into_iter().zip(mins).zip(maxs).enumerate();
288                    for (i, ((val, min), max)) in it {
289                        result[i] =
290                            $name { val: val.val, min: min.val, max: max.val };
291                    }
292                    result
293                }
294            }
295
296            #[inline]
297            pub(crate) fn get(self) -> $repr {
298                #[cfg(not(debug_assertions))]
299                {
300                    self.val
301                }
302                #[cfg(debug_assertions)]
303                {
304                    assert!(
305                        Self::contains(self.val),
306                        concat!(
307                            stringify!($name),
308                            " val {val:?} is not in range {MIN:?}..={MAX:?}"
309                        ),
310                        val = self.val,
311                        MIN = MIN,
312                        MAX = MAX,
313                    );
314                    assert!(
315                        Self::contains(self.min),
316                        concat!(
317                            stringify!($name),
318                            " min {min:?} is not in range {MIN:?}..={MAX:?}"
319                        ),
320                        min = self.min,
321                        MIN = MIN,
322                        MAX = MAX,
323                    );
324                    assert!(
325                        Self::contains(self.max),
326                        concat!(
327                            stringify!($name),
328                            " max {max:?} is not in range {MIN:?}..={MAX:?}"
329                        ),
330                        max = self.max,
331                        MIN = MIN,
332                        MAX = MAX,
333                    );
334                    self.val
335                }
336            }
337
338            /// Returns the underlying value without checking whether it's
339            /// in bounds or not.
340            ///
341            /// This should generally be avoided as it circumvents the
342            /// protections of this type. It is sometimes useful in cases
343            /// where the bounds are known not to matter. For example, in
344            /// producing an error message for checked arithmetic. It's also
345            /// good to use this in `Debug` impls for higher level types,
346            /// otherwise printing the debug representation of a type will fail
347            /// if a ranged integer is out of bounds. (And this is annoying.)
348            #[inline]
349            fn get_unchecked(self) -> $repr {
350                self.val
351            }
352
353            /// Turns this integer into an error.
354            ///
355            /// This is useful because it will use the integer's value even if
356            /// it falls outside of the bounds of this type.
357            ///
358            /// Callers can also use this routine to set custom context
359            /// dependent bounds. For example, when the day of the month is out
360            /// of bounds. The maximum value can vary based on the month (and
361            /// year).
362            #[inline]
363            pub(crate) fn to_error_with_bounds(
364                self,
365                what: &'static str,
366                min: impl Into<i128>,
367                max: impl Into<i128>,
368            ) -> Error {
369                Error::range(
370                    what,
371                    self.get_unchecked(),
372                    min.into(),
373                    max.into(),
374                )
375            }
376
377            #[inline]
378            pub(crate) fn abs(self) -> Self {
379                #[cfg(not(debug_assertions))]
380                {
381                    $name { val: self.val.abs() }
382                }
383                #[cfg(debug_assertions)]
384                {
385                    let val = self.val.checked_abs().expect(concat!(
386                        "absolute value of ",
387                        stringify!($name),
388                        " value overflowed",
389                    ));
390                    let min = self.min.checked_abs().expect(concat!(
391                        "absolute value of ",
392                        stringify!($name),
393                        " minimum overflowed",
394                    ));
395                    let max = self.max.checked_abs().expect(concat!(
396                        "absolute value of ",
397                        stringify!($name),
398                        " maximum overflowed",
399                    ));
400                    $name { val, min, max }
401                }
402            }
403
404            #[inline]
405            pub(crate) fn signum(self) -> $name<-1, 1> {
406                #[cfg(not(debug_assertions))]
407                {
408                    $name { val: self.val.signum() }
409                }
410                #[cfg(debug_assertions)]
411                {
412                    let val = self.val.signum();
413                    let min = self.min.signum();
414                    let max = self.max.signum();
415                    $name { val, min, max }
416                }
417            }
418
419            #[inline]
420            pub(crate) fn min(self, other: impl RInto<Self>) -> Self {
421                let other = other.rinto();
422                #[cfg(not(debug_assertions))]
423                {
424                    Self { val: self.val.min(other.val) }
425                }
426                #[cfg(debug_assertions)]
427                {
428                    let val = self.val.min(other.val);
429                    let min = self.val.min(other.min);
430                    let max = self.max.min(other.max);
431                    Self { val, min, max }
432                }
433            }
434
435            #[inline]
436            pub(crate) fn max(self, other: impl RInto<Self>) -> Self {
437                let other = other.rinto();
438                #[cfg(not(debug_assertions))]
439                {
440                    Self { val: self.val.max(other.val) }
441                }
442                #[cfg(debug_assertions)]
443                {
444                    let val = self.val.max(other.val);
445                    let min = self.val.max(other.min);
446                    let max = self.max.max(other.max);
447                    Self { val, min, max }
448                }
449            }
450
451            #[inline]
452            pub(crate) fn clamp(
453                self,
454                min: impl RInto<Self>,
455                max: impl RInto<Self>,
456            ) -> Self {
457                self.min(max).max(min)
458            }
459
460            #[inline]
461            pub(crate) fn div_ceil(self, rhs: impl RInto<Self>) -> Self {
462                let rhs = rhs.rinto();
463                #[cfg(not(debug_assertions))]
464                {
465                    let val = self.val.wrapping_div(rhs.val);
466                    Self { val }
467                }
468                #[cfg(debug_assertions)]
469                {
470                    let val = self.val.checked_div(rhs.val).expect(concat!(
471                        "dividing(ceil) ",
472                        stringify!($name),
473                        " values overflowed"
474                    ));
475                    let min = self.min.checked_div(rhs.min).expect(concat!(
476                        "dividing(ceil) ",
477                        stringify!($name),
478                        " minimums overflowed"
479                    ));
480                    let max = self.max.checked_div(rhs.max).expect(concat!(
481                        "dividing(ceil) ",
482                        stringify!($name),
483                        " maximums overflowed"
484                    ));
485                    Self { val, min, max }
486                }
487            }
488
489            #[inline]
490            pub(crate) fn div_floor(self, rhs: impl RInto<Self>) -> Self {
491                let rhs = rhs.rinto();
492                #[cfg(not(debug_assertions))]
493                {
494                    let val = self.val.wrapping_div_euclid(rhs.val);
495                    Self { val }
496                }
497                #[cfg(debug_assertions)]
498                {
499                    let val =
500                        self.val.checked_div_euclid(rhs.val).expect(concat!(
501                            "dividing(ceil) ",
502                            stringify!($name),
503                            " values overflowed"
504                        ));
505                    let min =
506                        self.min.checked_div_euclid(rhs.min).expect(concat!(
507                            "dividing(ceil) ",
508                            stringify!($name),
509                            " minimums overflowed"
510                        ));
511                    let max =
512                        self.max.checked_div_euclid(rhs.max).expect(concat!(
513                            "dividing(ceil) ",
514                            stringify!($name),
515                            " maximums overflowed"
516                        ));
517                    Self { val, min, max }
518                }
519            }
520
521            #[inline]
522            pub(crate) fn rem_ceil(self, rhs: impl RInto<Self>) -> Self {
523                let rhs = rhs.rinto();
524                #[cfg(not(debug_assertions))]
525                {
526                    let val = self.val.wrapping_rem(rhs.val);
527                    Self { val }
528                }
529                #[cfg(debug_assertions)]
530                {
531                    let val = self.val.checked_rem(rhs.val).expect(concat!(
532                        "modulo(ceil) ",
533                        stringify!($name),
534                        " values overflowed"
535                    ));
536                    let min = self.min.checked_rem(rhs.min).expect(concat!(
537                        "modulo(ceil) ",
538                        stringify!($name),
539                        " minimums overflowed"
540                    ));
541                    let max = self.max.checked_rem(rhs.max).expect(concat!(
542                        "modulo(ceil) ",
543                        stringify!($name),
544                        " maximums overflowed"
545                    ));
546                    Self { val, min, max }
547                }
548            }
549
550            #[inline]
551            pub(crate) fn rem_floor(self, rhs: impl RInto<Self>) -> Self {
552                let rhs = rhs.rinto();
553                #[cfg(not(debug_assertions))]
554                {
555                    let val = self.val.wrapping_rem_euclid(rhs.val);
556                    Self { val }
557                }
558                #[cfg(debug_assertions)]
559                {
560                    let val =
561                        self.val.checked_rem_euclid(rhs.val).expect(concat!(
562                            "modulo(ceil) ",
563                            stringify!($name),
564                            " values overflowed"
565                        ));
566                    let min =
567                        self.min.checked_rem_euclid(rhs.min).expect(concat!(
568                            "modulo(ceil) ",
569                            stringify!($name),
570                            " minimums overflowed"
571                        ));
572                    let max =
573                        self.max.checked_rem_euclid(rhs.max).expect(concat!(
574                            "modulo(ceil) ",
575                            stringify!($name),
576                            " maximums overflowed"
577                        ));
578                    Self { val, min, max }
579                }
580            }
581
582            #[inline]
583            pub(crate) fn try_checked_add(
584                self,
585                what: &'static str,
586                rhs: impl RInto<Self>,
587            ) -> Result<Self, Error> {
588                let rhs = rhs.rinto();
589                self.checked_add(rhs)
590                    .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
591            }
592
593            #[inline]
594            pub(crate) fn try_checked_sub(
595                self,
596                what: &'static str,
597                rhs: impl RInto<Self>,
598            ) -> Result<Self, Error> {
599                let rhs = rhs.rinto();
600                self.checked_sub(rhs)
601                    .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
602            }
603
604            #[inline]
605            pub(crate) fn try_checked_mul(
606                self,
607                what: &'static str,
608                rhs: impl RInto<Self>,
609            ) -> Result<Self, Error> {
610                let rhs = rhs.rinto();
611                self.checked_mul(rhs)
612                    .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
613            }
614
615            #[inline]
616            pub(crate) fn checked_add(
617                self,
618                rhs: impl RInto<Self>,
619            ) -> Option<Self> {
620                let rhs = rhs.rinto();
621                #[cfg(not(debug_assertions))]
622                {
623                    let val = self.val.checked_add(rhs.val)?;
624                    Self::new(val)
625                }
626                #[cfg(debug_assertions)]
627                {
628                    let val = self.val.checked_add(rhs.val)?;
629                    if !Self::contains(val) {
630                        return None;
631                    }
632                    // We specifically clamp min/max at the boundaries because
633                    // the checked arithmetic above implies we will catch
634                    // overflow. If we didn't do this, min/max arithmetic
635                    // could overflow even when the checked arithmetic above
636                    // did not. That is, under normal and expected operation,
637                    // we expect the min/max to eventually overflow even when
638                    // val does not.
639                    let min = self
640                        .min
641                        .saturating_add(rhs.min)
642                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
643                    let max = self
644                        .max
645                        .saturating_add(rhs.max)
646                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
647                    Some(Self { val, min, max })
648                }
649            }
650
651            #[inline]
652            pub(crate) fn checked_sub(
653                self,
654                rhs: impl RInto<Self>,
655            ) -> Option<Self> {
656                let rhs = rhs.rinto();
657                #[cfg(not(debug_assertions))]
658                {
659                    let val = self.val.checked_sub(rhs.val)?;
660                    Self::new(val)
661                }
662                #[cfg(debug_assertions)]
663                {
664                    let val = self.val.checked_sub(rhs.val)?;
665                    if !Self::contains(val) {
666                        return None;
667                    }
668                    // See comment in `checked_add`.
669                    let min = self
670                        .min
671                        .saturating_sub(rhs.min)
672                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
673                    let max = self
674                        .max
675                        .saturating_sub(rhs.max)
676                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
677                    Some(Self { val, min, max })
678                }
679            }
680
681            #[inline]
682            pub(crate) fn checked_mul(
683                self,
684                rhs: impl RInto<Self>,
685            ) -> Option<Self> {
686                let rhs = rhs.rinto();
687                #[cfg(not(debug_assertions))]
688                {
689                    let val = self.val.checked_mul(rhs.val)?;
690                    Self::new(val)
691                }
692                #[cfg(debug_assertions)]
693                {
694                    let val = self.val.checked_mul(rhs.val)?;
695                    if !Self::contains(val) {
696                        return None;
697                    }
698                    // See comment in `checked_add`.
699                    let min = self
700                        .min
701                        .saturating_mul(rhs.min)
702                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
703                    let max = self
704                        .max
705                        .saturating_mul(rhs.max)
706                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
707                    Some(Self { val, min, max })
708                }
709            }
710
711            #[inline]
712            pub(crate) fn wrapping_add(self, rhs: impl RInto<Self>) -> Self {
713                let rhs = rhs.rinto();
714                #[cfg(not(debug_assertions))]
715                {
716                    // When the min/max bounds match our primitive type, then
717                    // standard wrapping arithmetic will work fine. This is
718                    // likely a benefit for perf, but it's also required
719                    // for correctness since we don't support anything else
720                    // at the moment.
721                    if Self::IS_PRIMITIVE {
722                        Self { val: self.val.wrapping_add(rhs.val) }
723                    } else {
724                        unimplemented!(
725                            "wrapping arithmetic for non-primitive \
726                             ranged integers is not implemented yet",
727                        );
728                    }
729                }
730                #[cfg(debug_assertions)]
731                {
732                    if Self::IS_PRIMITIVE {
733                        let val = self.val.wrapping_add(rhs.val);
734                        let min = self.min.wrapping_add(rhs.min);
735                        let max = self.max.wrapping_add(rhs.max);
736                        Self { val, min, max }
737                    } else {
738                        unimplemented!(
739                            "wrapping arithmetic for non-primitive \
740                             ranged integers is not implemented yet",
741                        );
742                    }
743                }
744            }
745
746            #[inline]
747            pub(crate) fn wrapping_sub(self, rhs: impl RInto<Self>) -> Self {
748                let rhs = rhs.rinto();
749                #[cfg(not(debug_assertions))]
750                {
751                    // When the min/max bounds match our primitive type, then
752                    // standard wrapping arithmetic will work fine. This is
753                    // likely a benefit for perf, but it's also required
754                    // for correctness since we don't support anything else
755                    // at the moment.
756                    if Self::IS_PRIMITIVE {
757                        Self { val: self.val.wrapping_sub(rhs.val) }
758                    } else {
759                        unimplemented!(
760                            "wrapping arithmetic for non-primitive \
761                             ranged integers is not implemented yet",
762                        );
763                    }
764                }
765                #[cfg(debug_assertions)]
766                {
767                    if Self::IS_PRIMITIVE {
768                        let val = self.val.wrapping_sub(rhs.val);
769                        let min = self.min.wrapping_sub(rhs.min);
770                        let max = self.max.wrapping_sub(rhs.max);
771                        Self { val, min, max }
772                    } else {
773                        unimplemented!(
774                            "wrapping arithmetic for non-primitive \
775                             ranged integers is not implemented yet",
776                        );
777                    }
778                }
779            }
780
781            #[inline]
782            pub(crate) fn wrapping_mul(self, rhs: impl RInto<Self>) -> Self {
783                let rhs = rhs.rinto();
784                #[cfg(not(debug_assertions))]
785                {
786                    // When the min/max bounds match our primitive type, then
787                    // standard wrapping arithmetic will work fine. This is
788                    // likely a benefit for perf, but it's also required
789                    // for correctness since we don't support anything else
790                    // at the moment.
791                    if Self::IS_PRIMITIVE {
792                        Self { val: self.val.wrapping_mul(rhs.val) }
793                    } else {
794                        unimplemented!(
795                            "wrapping arithmetic for non-primitive \
796                             ranged integers is not implemented yet",
797                        );
798                    }
799                }
800                #[cfg(debug_assertions)]
801                {
802                    if Self::IS_PRIMITIVE {
803                        let val = self.val.wrapping_mul(rhs.val);
804                        let min = self.min.wrapping_mul(rhs.min);
805                        let max = self.max.wrapping_mul(rhs.max);
806                        Self { val, min, max }
807                    } else {
808                        unimplemented!(
809                            "wrapping arithmetic for non-primitive \
810                             ranged integers is not implemented yet",
811                        );
812                    }
813                }
814            }
815
816            #[inline]
817            pub(crate) fn saturating_add(self, rhs: impl RInto<Self>) -> Self {
818                let rhs = rhs.rinto();
819                #[cfg(not(debug_assertions))]
820                {
821                    let val = self
822                        .val
823                        .saturating_add(rhs.val)
824                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
825                    Self { val }
826                }
827                #[cfg(debug_assertions)]
828                {
829                    let val = self
830                        .val
831                        .saturating_add(rhs.val)
832                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
833                    let min = self
834                        .min
835                        .saturating_add(rhs.val)
836                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
837                    let max = self
838                        .max
839                        .saturating_add(rhs.val)
840                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
841                    Self { val, min, max }
842                }
843            }
844
845            #[inline]
846            pub(crate) fn saturating_sub(self, rhs: impl RInto<Self>) -> Self {
847                let rhs = rhs.rinto();
848                #[cfg(not(debug_assertions))]
849                {
850                    let val = self
851                        .val
852                        .saturating_sub(rhs.val)
853                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
854                    Self { val }
855                }
856                #[cfg(debug_assertions)]
857                {
858                    let val = self
859                        .val
860                        .saturating_sub(rhs.val)
861                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
862                    let min = self
863                        .min
864                        .saturating_sub(rhs.val)
865                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
866                    let max = self
867                        .max
868                        .saturating_sub(rhs.val)
869                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
870                    Self { val, min, max }
871                }
872            }
873
874            #[inline]
875            pub(crate) fn saturating_mul(self, rhs: impl RInto<Self>) -> Self {
876                let rhs = rhs.rinto();
877                #[cfg(not(debug_assertions))]
878                {
879                    let val = self
880                        .val
881                        .saturating_mul(rhs.val)
882                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
883                    Self { val }
884                }
885                #[cfg(debug_assertions)]
886                {
887                    let val = self
888                        .val
889                        .saturating_mul(rhs.val)
890                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
891                    let min = self
892                        .min
893                        .saturating_mul(rhs.val)
894                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
895                    let max = self
896                        .max
897                        .saturating_mul(rhs.val)
898                        .clamp(Self::MIN_REPR, Self::MAX_REPR);
899                    Self { val, min, max }
900                }
901            }
902
903            pub(crate) fn debug(self) -> RangedDebug<MIN, MAX> {
904                RangedDebug { rint: self.rinto() }
905            }
906        }
907
908        impl<
909            const MIN1: i128,
910            const MAX1: i128,
911            const MIN2: i128,
912            const MAX2: i128,
913        > RFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
914        {
915            #[inline]
916            fn rfrom(r: $name<MIN1, MAX1>) -> Self {
917                #[cfg(not(debug_assertions))]
918                {
919                    $name { val: r.val }
920                }
921                #[cfg(debug_assertions)]
922                {
923                    $name { val: r.val, min: r.min, max: r.max }
924                }
925            }
926        }
927
928        impl<const MIN: i128, const MAX: i128> RFrom<$name<MIN, MAX>>
929            for $repr
930        {
931            #[inline]
932            fn rfrom(r: $name<MIN, MAX>) -> $repr {
933                r.get()
934            }
935        }
936
937        impl<const MIN: i128, const MAX: i128> From<$name<MIN, MAX>>
938            for $repr
939        {
940            #[inline]
941            fn from(r: $name<MIN, MAX>) -> $repr {
942                r.get()
943            }
944        }
945
946        impl<const MIN: i128, const MAX: i128> RFrom<Constant>
947            for $name<MIN, MAX>
948        {
949            #[inline]
950            fn rfrom(c: Constant) -> Self {
951                #[cfg(not(debug_assertions))]
952                {
953                    Self { val: c.value() as $repr }
954                }
955                #[cfg(debug_assertions)]
956                {
957                    // We specifically allow constants that don't fit in the
958                    // bounds of the integer type, but we don't allow constans
959                    // that can't fit in the actual integer representation.
960                    // This makes doing things like `number % one-plus-max`
961                    // much more convenient.
962                    #[allow(irrefutable_let_patterns)]
963                    let Ok(val) = <$repr>::try_from(c.value()) else {
964                        panic!(
965                            "{c:?} does not fit in {name:?}",
966                            name = stringify!($name),
967                        )
968                    };
969                    Self { val, min: val, max: val }
970                }
971            }
972        }
973
974        impl<
975            const MIN1: i128,
976            const MAX1: i128,
977            const MIN2: i128,
978            const MAX2: i128,
979        > TryRFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
980        {
981            #[inline]
982            fn try_rfrom(
983                what: &'static str, r: $name<MIN1, MAX1>,
984            ) -> Result<Self, Error> {
985                #[cfg(not(debug_assertions))]
986                {
987                    if !Self::contains(r.val) {
988                        return Err(Self::error(what, r.val));
989                    }
990                    Ok($name { val: r.val })
991                }
992                #[cfg(debug_assertions)]
993                {
994                    if !Self::contains(r.val) {
995                        return Err(Self::error(what, r.val));
996                    }
997                    Ok($name {
998                        val: r.val,
999                        min: r.min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1000                        max: r.max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1001                    })
1002                }
1003            }
1004        }
1005
1006        $(
1007            impl<
1008                const MIN1: i128,
1009                const MAX1: i128,
1010                const MIN2: i128,
1011                const MAX2: i128,
1012            > RFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1013            {
1014                #[inline]
1015                fn rfrom(r: $smaller_name<MIN1, MAX1>) -> Self {
1016                    #[cfg(not(debug_assertions))]
1017                    {
1018                        Self { val: <$repr>::from(r.val) }
1019                    }
1020                    #[cfg(debug_assertions)]
1021                    {
1022                        Self {
1023                            val: <$repr>::from(r.val),
1024                            min: <$repr>::from(r.min),
1025                            max: <$repr>::from(r.max),
1026                        }
1027                    }
1028                }
1029            }
1030
1031            impl<
1032                const MIN: i128,
1033                const MAX: i128,
1034            > RFrom<$name<MIN, MAX>> for $smaller_repr
1035            {
1036                #[inline]
1037                fn rfrom(r: $name<MIN, MAX>) -> $smaller_repr {
1038                    #[cfg(not(debug_assertions))]
1039                    {
1040                        r.val as $smaller_repr
1041                    }
1042                    #[cfg(debug_assertions)]
1043                    {
1044                        let Ok(val) = <$smaller_repr>::try_from(r.val) else {
1045                            panic!(
1046                                "{from} value {val} does not fit in {to}",
1047                                from = stringify!($name),
1048                                val = r.val,
1049                                to = stringify!($smaller_name),
1050                            );
1051                        };
1052                        if <$smaller_repr>::try_from(r.min).is_err() {
1053                            panic!(
1054                                "{from} min value {val} does not fit in {to}",
1055                                from = stringify!($name),
1056                                val = r.min,
1057                                to = stringify!($smaller_name),
1058                            );
1059                        }
1060                        if <$smaller_repr>::try_from(r.max).is_err() {
1061                            panic!(
1062                                "{from} max value {val} does not fit in {to}",
1063                                from = stringify!($name),
1064                                val = r.max,
1065                                to = stringify!($smaller_name),
1066                            );
1067                        }
1068                        val
1069                    }
1070                }
1071            }
1072
1073            impl<
1074                const MIN: i128,
1075                const MAX: i128,
1076            > From<$name<MIN, MAX>> for $smaller_repr
1077            {
1078                #[inline]
1079                fn from(r: $name<MIN, MAX>) -> $smaller_repr {
1080                    <$smaller_repr>::rfrom(r)
1081                }
1082            }
1083
1084            impl<
1085                const MIN1: i128,
1086                const MAX1: i128,
1087                const MIN2: i128,
1088                const MAX2: i128,
1089            > TryRFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1090            {
1091                #[inline]
1092                fn try_rfrom(
1093                    what: &'static str, r: $smaller_name<MIN1, MAX1>,
1094                ) -> Result<Self, Error> {
1095                    #[cfg(not(debug_assertions))]
1096                    {
1097                        let val = <$repr>::from(r.val);
1098                        if !Self::contains(val) {
1099                            return Err(Self::error(what, val));
1100                        }
1101                        Ok(Self { val })
1102                    }
1103                    #[cfg(debug_assertions)]
1104                    {
1105                        let val = <$repr>::from(r.val);
1106                        if !Self::contains(val) {
1107                            return Err(Self::error(what, val));
1108                        }
1109                        Ok(Self {
1110                            val: val,
1111                            min: <$repr>::from(r.min)
1112                                .clamp(Self::MIN_REPR, Self::MAX_REPR),
1113                            max: <$repr>::from(r.max)
1114                                .clamp(Self::MIN_REPR, Self::MAX_REPR),
1115                        })
1116                    }
1117                }
1118            }
1119
1120            impl<
1121                const MIN1: i128,
1122                const MAX1: i128,
1123                const MIN2: i128,
1124                const MAX2: i128,
1125            > PartialEq<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1126            {
1127                #[inline]
1128                fn eq(&self, other: &$smaller_name<MIN1, MAX1>) -> bool {
1129                    self.eq(&Self::rfrom(*other))
1130                }
1131            }
1132
1133            impl<
1134                const MIN: i128,
1135                const MAX: i128,
1136            > PartialEq<$smaller_repr> for $name<MIN, MAX>
1137            {
1138                #[inline]
1139                fn eq(&self, other: &$smaller_repr) -> bool {
1140                    self.eq(&<$repr>::from(*other))
1141                }
1142            }
1143
1144            impl<
1145                const MIN1: i128,
1146                const MAX1: i128,
1147                const MIN2: i128,
1148                const MAX2: i128,
1149            > PartialOrd<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1150            {
1151                #[inline]
1152                fn partial_cmp(
1153                    &self,
1154                    other: &$smaller_name<MIN1, MAX1>,
1155                ) -> Option<Ordering> {
1156                    self.partial_cmp(&Self::rfrom(*other))
1157                }
1158            }
1159
1160            impl<
1161                const MIN: i128,
1162                const MAX: i128,
1163            > PartialOrd<$smaller_repr> for $name<MIN, MAX>
1164            {
1165                #[inline]
1166                fn partial_cmp(
1167                    &self,
1168                    other: &$smaller_repr,
1169                ) -> Option<Ordering> {
1170                    self.partial_cmp(&<$repr>::from(*other))
1171                }
1172            }
1173
1174            impl<
1175                const MIN1: i128,
1176                const MAX1: i128,
1177                const MIN2: i128,
1178                const MAX2: i128,
1179            > Add<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1180            {
1181                type Output = Self;
1182
1183                #[inline]
1184                fn add(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1185                    self.add(Self::rfrom(rhs))
1186                }
1187            }
1188
1189            impl<
1190                const MIN1: i128,
1191                const MAX1: i128,
1192                const MIN2: i128,
1193                const MAX2: i128,
1194            > AddAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1195            {
1196                #[inline]
1197                fn add_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1198                    self.add_assign(Self::rfrom(rhs))
1199                }
1200            }
1201
1202            impl<
1203                const MIN1: i128,
1204                const MAX1: i128,
1205                const MIN2: i128,
1206                const MAX2: i128,
1207            > Sub<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1208            {
1209                type Output = Self;
1210
1211                #[inline]
1212                fn sub(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1213                    self.sub(Self::rfrom(rhs))
1214                }
1215            }
1216
1217            impl<
1218                const MIN1: i128,
1219                const MAX1: i128,
1220                const MIN2: i128,
1221                const MAX2: i128,
1222            > SubAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1223            {
1224                #[inline]
1225                fn sub_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1226                    self.sub_assign(Self::rfrom(rhs))
1227                }
1228            }
1229
1230            impl<
1231                const MIN1: i128,
1232                const MAX1: i128,
1233                const MIN2: i128,
1234                const MAX2: i128,
1235            > Mul<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1236            {
1237                type Output = Self;
1238
1239                #[inline]
1240                fn mul(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1241                    self.mul(Self::rfrom(rhs))
1242                }
1243            }
1244
1245            impl<
1246                const MIN1: i128,
1247                const MAX1: i128,
1248                const MIN2: i128,
1249                const MAX2: i128,
1250            > MulAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1251            {
1252                #[inline]
1253                fn mul_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1254                    self.mul_assign(Self::rfrom(rhs))
1255                }
1256            }
1257
1258            impl<
1259                const MIN1: i128,
1260                const MAX1: i128,
1261                const MIN2: i128,
1262                const MAX2: i128,
1263            > Div<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1264            {
1265                type Output = Self;
1266
1267                #[inline]
1268                fn div(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1269                    self.div(Self::rfrom(rhs))
1270                }
1271            }
1272
1273            impl<
1274                const MIN1: i128,
1275                const MAX1: i128,
1276                const MIN2: i128,
1277                const MAX2: i128,
1278            > DivAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1279            {
1280                #[inline]
1281                fn div_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1282                    self.div_assign(Self::rfrom(rhs))
1283                }
1284            }
1285
1286            impl<
1287                const MIN1: i128,
1288                const MAX1: i128,
1289                const MIN2: i128,
1290                const MAX2: i128,
1291            > Rem<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1292            {
1293                type Output = Self;
1294
1295                #[inline]
1296                fn rem(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1297                    self.rem(Self::rfrom(rhs))
1298                }
1299            }
1300
1301            impl<
1302                const MIN1: i128,
1303                const MAX1: i128,
1304                const MIN2: i128,
1305                const MAX2: i128,
1306            > RemAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1307            {
1308                #[inline]
1309                fn rem_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1310                    self.rem_assign(Self::rfrom(rhs))
1311                }
1312            }
1313        )*
1314
1315        $(
1316            impl<
1317                const MIN1: i128,
1318                const MAX1: i128,
1319                const MIN2: i128,
1320                const MAX2: i128,
1321            > RFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1322            {
1323                #[inline]
1324                fn rfrom(r: $bigger_name<MIN1, MAX1>) -> Self {
1325                    #[cfg(not(debug_assertions))]
1326                    {
1327                        Self { val: r.val as $repr }
1328                    }
1329                    #[cfg(debug_assertions)]
1330                    {
1331                        let Ok(val) = <$repr>::try_from(r.val) else {
1332                            panic!(
1333                                "{from} value {val} does not fit in {to}",
1334                                from = stringify!($bigger_name),
1335                                val = r.val,
1336                                to = stringify!($name),
1337                            );
1338                        };
1339                        let Ok(min) = <$repr>::try_from(r.min) else {
1340                            panic!(
1341                                "{from} min value {val} does not fit in {to}",
1342                                from = stringify!($bigger_name),
1343                                val = r.min,
1344                                to = stringify!($name),
1345                            );
1346                        };
1347                        let Ok(max) = <$repr>::try_from(r.max) else {
1348                            panic!(
1349                                "{from} max value {val} does not fit in {to}",
1350                                from = stringify!($bigger_name),
1351                                val = r.max,
1352                                to = stringify!($name),
1353                            );
1354                        };
1355                        Self { val, min, max }
1356                    }
1357                }
1358            }
1359
1360            impl<
1361                const MIN: i128,
1362                const MAX: i128,
1363            > RFrom<$name<MIN, MAX>> for $bigger_repr
1364            {
1365                #[inline]
1366                fn rfrom(r: $name<MIN, MAX>) -> $bigger_repr {
1367                    <$bigger_repr>::from(r.get())
1368                }
1369            }
1370
1371            impl<
1372                const MIN: i128,
1373                const MAX: i128,
1374            > From<$name<MIN, MAX>> for $bigger_repr
1375            {
1376                #[inline]
1377                fn from(r: $name<MIN, MAX>) -> $bigger_repr {
1378                    <$bigger_repr>::rfrom(r)
1379                }
1380            }
1381
1382            impl<
1383                const MIN1: i128,
1384                const MAX1: i128,
1385                const MIN2: i128,
1386                const MAX2: i128,
1387            > TryRFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1388            {
1389                #[inline]
1390                fn try_rfrom(
1391                    what: &'static str, r: $bigger_name<MIN1, MAX1>,
1392                ) -> Result<Self, Error> {
1393                    #[cfg(not(debug_assertions))]
1394                    {
1395                        let val = <$repr>::try_from(r.val).map_err(|_| {
1396                            Error::range(what, r.val, MIN2, MAX2)
1397                        })?;
1398                        if !Self::contains(val) {
1399                            return Err(Self::error(what, val));
1400                        }
1401                        Ok(Self { val })
1402                    }
1403                    #[cfg(debug_assertions)]
1404                    {
1405                        let val = <$repr>::try_from(r.val).map_err(|_| {
1406                            Error::range(what, r.val, MIN2, MAX2)
1407                        })?;
1408                        if !Self::contains(val) {
1409                            return Err(Self::error(what, val));
1410                        }
1411                        let min = <$repr>::try_from(r.min).unwrap_or_else(|_| {
1412                            if (r.min as i128) < MIN2 {
1413                                Self::MIN_REPR
1414                            } else {
1415                                assert!(r.min as i128 > MAX2);
1416                                Self::MAX_REPR
1417                            }
1418                        });
1419                        let max = <$repr>::try_from(r.max).unwrap_or_else(|_| {
1420                            if (r.max as i128) < MIN2 {
1421                                Self::MIN_REPR
1422                            } else {
1423                                assert!(r.max as i128 > MAX2);
1424                                Self::MAX_REPR
1425                            }
1426                        });
1427                        Ok(Self {
1428                            val,
1429                            min: min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1430                            max: max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1431                        })
1432                    }
1433                }
1434            }
1435
1436            impl<
1437                const MIN1: i128,
1438                const MAX1: i128,
1439                const MIN2: i128,
1440                const MAX2: i128,
1441            > PartialEq<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1442            {
1443                #[inline]
1444                fn eq(&self, other: &$bigger_name<MIN1, MAX1>) -> bool {
1445                    <$bigger_name<MIN1, MAX1>>::rfrom(*self).eq(other)
1446                }
1447            }
1448
1449            impl<
1450                const MIN: i128,
1451                const MAX: i128,
1452            > PartialEq<$bigger_repr> for $name<MIN, MAX>
1453            {
1454                #[inline]
1455                fn eq(&self, other: &$bigger_repr) -> bool {
1456                    <$bigger_name<MIN, MAX>>::rfrom(*self).eq(other)
1457                }
1458            }
1459
1460            impl<
1461                const MIN1: i128,
1462                const MAX1: i128,
1463                const MIN2: i128,
1464                const MAX2: i128,
1465            > PartialOrd<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1466            {
1467                #[inline]
1468                fn partial_cmp(
1469                    &self,
1470                    other: &$bigger_name<MIN1, MAX1>,
1471                ) -> Option<Ordering> {
1472                    <$bigger_name<MIN1, MAX1>>::rfrom(*self).partial_cmp(other)
1473                }
1474            }
1475
1476            impl<
1477                const MIN: i128,
1478                const MAX: i128,
1479            > PartialOrd<$bigger_repr> for $name<MIN, MAX>
1480            {
1481                #[inline]
1482                fn partial_cmp(
1483                    &self,
1484                    other: &$bigger_repr,
1485                ) -> Option<Ordering> {
1486                    <$bigger_name<MIN, MAX>>::rfrom(*self).partial_cmp(other)
1487                }
1488            }
1489
1490            impl<
1491                const MIN1: i128,
1492                const MAX1: i128,
1493                const MIN2: i128,
1494                const MAX2: i128,
1495            > Add<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1496            {
1497                type Output = Self;
1498
1499                #[inline]
1500                fn add(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1501                    self.add(Self::rfrom(rhs))
1502                }
1503            }
1504
1505            impl<
1506                const MIN1: i128,
1507                const MAX1: i128,
1508                const MIN2: i128,
1509                const MAX2: i128,
1510            > AddAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1511            {
1512                #[inline]
1513                fn add_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1514                    self.add_assign(Self::rfrom(rhs))
1515                }
1516            }
1517
1518            impl<
1519                const MIN1: i128,
1520                const MAX1: i128,
1521                const MIN2: i128,
1522                const MAX2: i128,
1523            > Sub<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1524            {
1525                type Output = Self;
1526
1527                #[inline]
1528                fn sub(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1529                    self.sub(Self::rfrom(rhs))
1530                }
1531            }
1532
1533            impl<
1534                const MIN1: i128,
1535                const MAX1: i128,
1536                const MIN2: i128,
1537                const MAX2: i128,
1538            > SubAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1539            {
1540                #[inline]
1541                fn sub_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1542                    self.sub_assign(Self::rfrom(rhs))
1543                }
1544            }
1545
1546            impl<
1547                const MIN1: i128,
1548                const MAX1: i128,
1549                const MIN2: i128,
1550                const MAX2: i128,
1551            > Mul<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1552            {
1553                type Output = Self;
1554
1555                #[inline]
1556                fn mul(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1557                    self.mul(Self::rfrom(rhs))
1558                }
1559            }
1560
1561            impl<
1562                const MIN1: i128,
1563                const MAX1: i128,
1564                const MIN2: i128,
1565                const MAX2: i128,
1566            > MulAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1567            {
1568                #[inline]
1569                fn mul_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1570                    self.mul_assign(Self::rfrom(rhs))
1571                }
1572            }
1573
1574            impl<
1575                const MIN1: i128,
1576                const MAX1: i128,
1577                const MIN2: i128,
1578                const MAX2: i128,
1579            > Div<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1580            {
1581                type Output = Self;
1582
1583                #[inline]
1584                fn div(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1585                    self.div(Self::rfrom(rhs))
1586                }
1587            }
1588
1589            impl<
1590                const MIN1: i128,
1591                const MAX1: i128,
1592                const MIN2: i128,
1593                const MAX2: i128,
1594            > DivAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1595            {
1596                #[inline]
1597                fn div_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1598                    self.div_assign(Self::rfrom(rhs))
1599                }
1600            }
1601
1602            impl<
1603                const MIN1: i128,
1604                const MAX1: i128,
1605                const MIN2: i128,
1606                const MAX2: i128,
1607            > Rem<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1608            {
1609                type Output = Self;
1610
1611                #[inline]
1612                fn rem(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1613                    self.rem(Self::rfrom(rhs))
1614                }
1615            }
1616
1617            impl<
1618                const MIN1: i128,
1619                const MAX1: i128,
1620                const MIN2: i128,
1621                const MAX2: i128,
1622            > RemAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1623            {
1624                #[inline]
1625                fn rem_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1626                    self.rem_assign(Self::rfrom(rhs))
1627                }
1628            }
1629        )*
1630
1631        impl<const MIN: i128, const MAX: i128> Neg for $name<MIN, MAX> {
1632            type Output = Self;
1633
1634            #[inline]
1635            fn neg(self) -> Self {
1636                #[cfg(not(debug_assertions))]
1637                {
1638                    let val = self.val.wrapping_neg();
1639                    Self { val }
1640                }
1641                #[cfg(debug_assertions)]
1642                {
1643                    let val = self.val.checked_neg().expect(concat!(
1644                        "negating ",
1645                        stringify!($name),
1646                        " values overflowed"
1647                    ));
1648                    let min = self.min.checked_neg().expect(concat!(
1649                        "negating ",
1650                        stringify!($name),
1651                        " minimums overflowed"
1652                    ));
1653                    let max = self.max.checked_neg().expect(concat!(
1654                        "negating ",
1655                        stringify!($name),
1656                        " maximums overflowed"
1657                    ));
1658                    Self { val, min, max }
1659                }
1660            }
1661        }
1662
1663        impl<
1664            const MIN1: i128,
1665            const MAX1: i128,
1666            const MIN2: i128,
1667            const MAX2: i128,
1668        > Add<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1669            type Output = Self;
1670
1671            #[inline]
1672            fn add(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1673                #[cfg(not(debug_assertions))]
1674                {
1675                    let val = self.val.wrapping_add(rhs.val);
1676                    Self { val }
1677                }
1678                #[cfg(debug_assertions)]
1679                {
1680                    let val = self.val.checked_add(rhs.val).expect(concat!(
1681                        "adding ",
1682                        stringify!($name),
1683                        " values overflowed"
1684                    ));
1685                    let min = self.min.checked_add(rhs.min).expect(concat!(
1686                        "adding ",
1687                        stringify!($name),
1688                        " minimums overflowed"
1689                    ));
1690                    let max = self.max.checked_add(rhs.max).expect(concat!(
1691                        "adding ",
1692                        stringify!($name),
1693                        " maximums overflowed"
1694                    ));
1695                    Self { val, min, max }
1696                }
1697            }
1698        }
1699
1700        impl<
1701            const MIN1: i128,
1702            const MAX1: i128,
1703            const MIN2: i128,
1704            const MAX2: i128,
1705        > AddAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1706            #[inline]
1707            fn add_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1708                *self = self.add(rhs);
1709            }
1710        }
1711
1712        impl<
1713            const MIN1: i128,
1714            const MAX1: i128,
1715            const MIN2: i128,
1716            const MAX2: i128,
1717        > Sub<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1718            type Output = Self;
1719
1720            #[inline]
1721            fn sub(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1722                #[cfg(not(debug_assertions))]
1723                {
1724                    let val = self.val.wrapping_sub(rhs.val);
1725                    Self { val }
1726                }
1727                #[cfg(debug_assertions)]
1728                {
1729                    let val = self.val.checked_sub(rhs.val).expect(concat!(
1730                        "subtracting ",
1731                        stringify!($name),
1732                        " values overflowed"
1733                    ));
1734                    let min = self.min.checked_sub(rhs.min).expect(concat!(
1735                        "subtracting ",
1736                        stringify!($name),
1737                        " minimums overflowed"
1738                    ));
1739                    let max = self.max.checked_sub(rhs.max).expect(concat!(
1740                        "subtracting ",
1741                        stringify!($name),
1742                        " maximums overflowed"
1743                    ));
1744                    Self { val, min, max }
1745                }
1746            }
1747        }
1748
1749        impl<
1750            const MIN1: i128,
1751            const MAX1: i128,
1752            const MIN2: i128,
1753            const MAX2: i128,
1754        > SubAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1755            #[inline]
1756            fn sub_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1757                *self = self.sub(rhs);
1758            }
1759        }
1760
1761        impl<
1762            const MIN1: i128,
1763            const MAX1: i128,
1764            const MIN2: i128,
1765            const MAX2: i128,
1766        > Mul<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1767            type Output = Self;
1768
1769            #[inline]
1770            fn mul(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1771                #[cfg(not(debug_assertions))]
1772                {
1773                    let val = self.val.wrapping_mul(rhs.val);
1774                    Self { val }
1775                }
1776                #[cfg(debug_assertions)]
1777                {
1778                    let val = self.val.checked_mul(rhs.val).expect(concat!(
1779                        "multiplying ",
1780                        stringify!($name),
1781                        " values overflowed"
1782                    ));
1783                    let min = self.min.checked_mul(rhs.min).expect(concat!(
1784                        "multiplying ",
1785                        stringify!($name),
1786                        " minimums overflowed"
1787                    ));
1788                    let max = self.max.checked_mul(rhs.max).expect(concat!(
1789                        "multiplying ",
1790                        stringify!($name),
1791                        " maximums overflowed"
1792                    ));
1793                    Self { val, min, max }
1794                }
1795            }
1796        }
1797
1798        impl<
1799            const MIN1: i128,
1800            const MAX1: i128,
1801            const MIN2: i128,
1802            const MAX2: i128,
1803        > MulAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1804            #[inline]
1805            fn mul_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1806                *self = self.mul(rhs);
1807            }
1808        }
1809
1810        impl<
1811            const MIN1: i128,
1812            const MAX1: i128,
1813            const MIN2: i128,
1814            const MAX2: i128,
1815        > Div<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1816            type Output = Self;
1817
1818            #[inline]
1819            fn div(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1820                #[cfg(not(debug_assertions))]
1821                {
1822                    let val = self.val.wrapping_div_euclid(rhs.val);
1823                    Self { val }
1824                }
1825                #[cfg(debug_assertions)]
1826                {
1827                    let val =
1828                        self.val.checked_div_euclid(rhs.val).expect(concat!(
1829                            "dividing ",
1830                            stringify!($name),
1831                            " values overflowed"
1832                        ));
1833                    let min =
1834                        self.min.checked_div_euclid(rhs.min).expect(concat!(
1835                            "dividing ",
1836                            stringify!($name),
1837                            " minimums overflowed"
1838                        ));
1839                    let max =
1840                        self.max.checked_div_euclid(rhs.max).expect(concat!(
1841                            "dividing ",
1842                            stringify!($name),
1843                            " maximums overflowed"
1844                        ));
1845                    Self { val, min, max }
1846                }
1847            }
1848        }
1849
1850        impl<
1851            const MIN1: i128,
1852            const MAX1: i128,
1853            const MIN2: i128,
1854            const MAX2: i128,
1855        > DivAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1856            #[inline]
1857            fn div_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1858                *self = self.div(rhs);
1859            }
1860        }
1861
1862        impl<
1863            const MIN1: i128,
1864            const MAX1: i128,
1865            const MIN2: i128,
1866            const MAX2: i128,
1867        > Rem<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1868            type Output = Self;
1869
1870            #[inline]
1871            fn rem(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1872                #[cfg(not(debug_assertions))]
1873                {
1874                    let val = self.val.wrapping_rem_euclid(rhs.val);
1875                    Self { val }
1876                }
1877                #[cfg(debug_assertions)]
1878                {
1879                    let val =
1880                        self.val.checked_rem_euclid(rhs.val).expect(concat!(
1881                            "modulo ",
1882                            stringify!($name),
1883                            " values overflowed"
1884                        ));
1885                    let min =
1886                        self.min.checked_rem_euclid(rhs.min).expect(concat!(
1887                            "modulo ",
1888                            stringify!($name),
1889                            " minimums overflowed"
1890                        ));
1891                    let max =
1892                        self.max.checked_rem_euclid(rhs.max).expect(concat!(
1893                            "modulo ",
1894                            stringify!($name),
1895                            " maximums overflowed"
1896                        ));
1897                    Self { val, min, max }
1898                }
1899            }
1900        }
1901
1902        impl<
1903            const MIN1: i128,
1904            const MAX1: i128,
1905            const MIN2: i128,
1906            const MAX2: i128,
1907        > RemAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1908            #[inline]
1909            fn rem_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1910                *self = self.rem(rhs);
1911            }
1912        }
1913
1914        impl<const MIN: i128, const MAX: i128> Add<$name<MIN, MAX>>
1915            for Constant
1916        {
1917            type Output = $name<MIN, MAX>;
1918
1919            #[inline]
1920            fn add(self, rhs: $name<MIN, MAX>) -> Self::Output {
1921                $name::rfrom(self).add(rhs)
1922            }
1923        }
1924
1925        impl<const MIN: i128, const MAX: i128> Add<Constant> for $name<MIN, MAX> {
1926            type Output = $name<MIN, MAX>;
1927
1928            #[inline]
1929            fn add(self, rhs: Constant) -> Self::Output {
1930                self.add(Self::rfrom(rhs))
1931            }
1932        }
1933
1934        impl<const MIN: i128, const MAX: i128> AddAssign<Constant> for $name<MIN, MAX> {
1935            #[inline]
1936            fn add_assign(&mut self, rhs: Constant) {
1937                self.add_assign(Self::rfrom(rhs))
1938            }
1939        }
1940
1941        impl<const MIN: i128, const MAX: i128> Sub<$name<MIN, MAX>> for Constant {
1942            type Output = $name<MIN, MAX>;
1943
1944            #[inline]
1945            fn sub(self, rhs: $name<MIN, MAX>) -> Self::Output {
1946                $name::rfrom(self).sub(rhs)
1947            }
1948        }
1949
1950        impl<const MIN: i128, const MAX: i128> Sub<Constant> for $name<MIN, MAX> {
1951            type Output = $name<MIN, MAX>;
1952
1953            #[inline]
1954            fn sub(self, rhs: Constant) -> Self::Output {
1955                self.sub(Self::rfrom(rhs))
1956            }
1957        }
1958
1959        impl<const MIN: i128, const MAX: i128> SubAssign<Constant> for $name<MIN, MAX> {
1960            #[inline]
1961            fn sub_assign(&mut self, rhs: Constant) {
1962                self.sub_assign(Self::rfrom(rhs))
1963            }
1964        }
1965
1966        impl<const MIN: i128, const MAX: i128> Mul<$name<MIN, MAX>> for Constant {
1967            type Output = $name<MIN, MAX>;
1968
1969            #[inline]
1970            fn mul(self, rhs: $name<MIN, MAX>) -> Self::Output {
1971                $name::rfrom(self).mul(rhs)
1972            }
1973        }
1974
1975        impl<const MIN: i128, const MAX: i128> Mul<Constant> for $name<MIN, MAX> {
1976            type Output = $name<MIN, MAX>;
1977
1978            #[inline]
1979            fn mul(self, rhs: Constant) -> Self::Output {
1980                self.mul(Self::rfrom(rhs))
1981            }
1982        }
1983
1984        impl<const MIN: i128, const MAX: i128> MulAssign<Constant> for $name<MIN, MAX> {
1985            #[inline]
1986            fn mul_assign(&mut self, rhs: Constant) {
1987                self.mul_assign(Self::rfrom(rhs))
1988            }
1989        }
1990
1991        impl<const MIN: i128, const MAX: i128> Div<$name<MIN, MAX>> for Constant {
1992            type Output = $name<MIN, MAX>;
1993
1994            #[inline]
1995            fn div(self, rhs: $name<MIN, MAX>) -> Self::Output {
1996                $name::rfrom(self).div(rhs)
1997            }
1998        }
1999
2000        impl<const MIN: i128, const MAX: i128> Div<Constant> for $name<MIN, MAX> {
2001            type Output = $name<MIN, MAX>;
2002
2003            #[inline]
2004            fn div(self, rhs: Constant) -> Self::Output {
2005                self.div(Self::rfrom(rhs))
2006            }
2007        }
2008        impl<const MIN: i128, const MAX: i128> DivAssign<Constant> for $name<MIN, MAX> {
2009            #[inline]
2010            fn div_assign(&mut self, rhs: Constant) {
2011                self.div_assign(Self::rfrom(rhs))
2012            }
2013        }
2014
2015        impl<const MIN: i128, const MAX: i128> Rem<$name<MIN, MAX>> for Constant {
2016            type Output = $name<MIN, MAX>;
2017
2018            #[inline]
2019            fn rem(self, rhs: $name<MIN, MAX>) -> Self::Output {
2020                $name::rfrom(self).rem(rhs)
2021            }
2022        }
2023
2024        impl<const MIN: i128, const MAX: i128> Rem<Constant> for $name<MIN, MAX> {
2025            type Output = $name<MIN, MAX>;
2026
2027            #[inline]
2028            fn rem(self, rhs: Constant) -> Self::Output {
2029                self.rem(Self::rfrom(rhs))
2030            }
2031        }
2032        impl<const MIN: i128, const MAX: i128> RemAssign<Constant> for $name<MIN, MAX> {
2033            #[inline]
2034            fn rem_assign(&mut self, rhs: Constant) {
2035                self.rem_assign(Self::rfrom(rhs))
2036            }
2037        }
2038
2039        impl<const MIN: i128, const MAX: i128> Eq for $name<MIN, MAX> {}
2040
2041        impl<
2042            const MIN1: i128,
2043            const MAX1: i128,
2044            const MIN2: i128,
2045            const MAX2: i128,
2046        > PartialEq<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2047            #[inline]
2048            fn eq(&self, other: &$name<MIN2, MAX2>) -> bool {
2049                self.val.eq(&other.val)
2050            }
2051        }
2052
2053        impl<const MIN: i128, const MAX: i128> PartialEq<Constant> for $name<MIN, MAX> {
2054            #[inline]
2055            fn eq(&self, other: &Constant) -> bool {
2056                self.val.eq(&<$repr>::from(*other))
2057            }
2058        }
2059
2060        impl<const MIN: i128, const MAX: i128> PartialEq<$name<MIN, MAX>> for Constant {
2061            #[inline]
2062            fn eq(&self, other: &$name<MIN, MAX>) -> bool {
2063                <$repr>::from(*self).eq(&other.val)
2064            }
2065        }
2066
2067        impl<const MIN: i128, const MAX: i128> PartialEq<$repr> for $name<MIN, MAX> {
2068            #[inline]
2069            fn eq(&self, other: &$repr) -> bool {
2070                self.val.eq(other)
2071            }
2072        }
2073
2074        impl<const MIN: i128, const MAX: i128> PartialEq<$name<MIN, MAX>> for $repr {
2075            #[inline]
2076            fn eq(&self, other: &$name<MIN, MAX>) -> bool {
2077                self.eq(&other.val)
2078            }
2079        }
2080
2081        impl<const MIN: i128, const MAX: i128> Ord for $name<MIN, MAX> {
2082            #[inline]
2083            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2084                self.val.cmp(&other.val)
2085            }
2086        }
2087
2088        impl<
2089            const MIN1: i128,
2090            const MAX1: i128,
2091            const MIN2: i128,
2092            const MAX2: i128,
2093        > PartialOrd<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2094            #[inline]
2095            fn partial_cmp(
2096                &self,
2097                other: &$name<MIN2, MAX2>,
2098            ) -> Option<core::cmp::Ordering> {
2099                self.val.partial_cmp(&other.val)
2100            }
2101        }
2102
2103        impl<const MIN: i128, const MAX: i128> PartialOrd<Constant> for $name<MIN, MAX> {
2104            #[inline]
2105            fn partial_cmp(
2106                &self,
2107                other: &Constant,
2108            ) -> Option<core::cmp::Ordering> {
2109                self.val.partial_cmp(&<$repr>::from(*other))
2110            }
2111        }
2112
2113        impl<const MIN: i128, const MAX: i128> PartialOrd<$name<MIN, MAX>> for Constant {
2114            #[inline]
2115            fn partial_cmp(
2116                &self,
2117                other: &$name<MIN, MAX>,
2118            ) -> Option<core::cmp::Ordering> {
2119                <$repr>::from(*self).partial_cmp(&other.val)
2120            }
2121        }
2122
2123        impl<const MIN: i128, const MAX: i128> PartialOrd<$repr> for $name<MIN, MAX> {
2124            #[inline]
2125            fn partial_cmp(
2126                &self,
2127                other: &$repr,
2128            ) -> Option<core::cmp::Ordering> {
2129                self.val.partial_cmp(other)
2130            }
2131        }
2132
2133        impl<const MIN: i128, const MAX: i128> PartialOrd<$name<MIN, MAX>> for $repr {
2134            #[inline]
2135            fn partial_cmp(
2136                &self,
2137                other: &$name<MIN, MAX>,
2138            ) -> Option<core::cmp::Ordering> {
2139                self.partial_cmp(&other.val)
2140            }
2141        }
2142
2143        impl<const MIN: i128, const MAX: i128> core::fmt::Display for $name<MIN, MAX> {
2144            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2145                // We do this dance here because a Display impl is often used
2146                // when formatting a panic message, and panicking in this
2147                // context is supremely annoying because it causes an instant
2148                // abort. So if this value is not in bounds, then we write out
2149                // its debug repr which should show some nice output.
2150                match self.checked_add(Self::N::<0>()) {
2151                    Some(val) => core::fmt::Display::fmt(&val.get(), f),
2152                    None => write!(f, "{:?}", self),
2153                }
2154            }
2155        }
2156
2157        impl<const MIN: i128, const MAX: i128> core::fmt::Debug for $name<MIN, MAX> {
2158            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2159                self.debug().fmt(f)
2160                /*
2161                if !f.alternate() {
2162                    self.debug().fmt(f)
2163                } else {
2164                    #[cfg(not(debug_assertions))]
2165                    {
2166                        f.debug_struct(stringify!($name))
2167                            .field("val", &self.val)
2168                            .field("MIN", &MIN)
2169                            .field("MAX", &MAX)
2170                            .finish()
2171                    }
2172                    #[cfg(debug_assertions)]
2173                    {
2174                        f.debug_struct(stringify!($name))
2175                            .field("val", &self.val)
2176                            .field("MIN", &MIN)
2177                            .field("MAX", &MAX)
2178                            .field("computed_min", &self.min)
2179                            .field("computed_max", &self.max)
2180                            .finish()
2181                    }
2182                }
2183                */
2184            }
2185        }
2186
2187        #[cfg(test)]
2188        impl<const MIN: i128, const MAX: i128> quickcheck::Arbitrary for $name<MIN, MAX> {
2189            fn arbitrary(g: &mut quickcheck::Gen) -> Self {
2190                let mut n: $repr = <$repr>::arbitrary(g);
2191                if !Self::IS_PRIMITIVE {
2192                    n = n.wrapping_rem_euclid(Self::LEN as $repr);
2193                    n += Self::MIN_REPR;
2194                }
2195                Self::new(n).unwrap()
2196            }
2197
2198            fn shrink(&self) -> alloc::boxed::Box<dyn Iterator<Item = Self>> {
2199                alloc::boxed::Box::new(self.val.shrink().filter_map(Self::new))
2200            }
2201        }
2202    };
2203}
2204
2205define_ranged!(ri8, i8, smaller {}, bigger { ri16 i16, ri32 i32, ri64 i64, ri128 i128 });
2206define_ranged!(ri16, i16, smaller { ri8 i8 }, bigger { ri32 i32, ri64 i64, ri128 i128 });
2207define_ranged!(ri32, i32, smaller { ri8 i8, ri16 i16 }, bigger { ri64 i64, ri128 i128 });
2208define_ranged!(ri64, i64, smaller { ri8 i8, ri16 i16, ri32 i32 }, bigger { ri128 i128 });
2209define_ranged!(ri128, i128, smaller { ri8 i8, ri16 i16, ri32 i32, ri64 i64 }, bigger {});
2210
2211impl<const MIN: i128, const MAX: i128> ri8<MIN, MAX> {
2212    #[inline]
2213    pub(crate) fn without_bounds(
2214        self,
2215    ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2216        ri64::rfrom(self)
2217    }
2218}
2219
2220impl<const MIN: i128, const MAX: i128> ri16<MIN, MAX> {
2221    #[inline]
2222    pub(crate) fn without_bounds(
2223        self,
2224    ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2225        ri64::rfrom(self)
2226    }
2227}
2228
2229impl<const MIN: i128, const MAX: i128> ri32<MIN, MAX> {
2230    #[inline]
2231    pub(crate) fn without_bounds(
2232        self,
2233    ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2234        ri64::rfrom(self)
2235    }
2236}
2237
2238impl<const MIN: i128, const MAX: i128> ri64<MIN, MAX> {
2239    #[inline]
2240    pub(crate) fn without_bounds(
2241        self,
2242    ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2243        ri64::rfrom(self)
2244    }
2245}
2246
2247impl<const MIN: i128, const MAX: i128> ri128<MIN, MAX> {
2248    #[inline]
2249    pub(crate) fn without_bounds(self) -> ri128<{ i128::MIN }, { i128::MAX }> {
2250        ri128::rfrom(self)
2251    }
2252}
2253
2254pub(crate) struct RangedDebug<const MIN: i128, const MAX: i128> {
2255    rint: ri128<MIN, MAX>,
2256}
2257
2258impl<const MIN: i128, const MAX: i128> core::fmt::Debug
2259    for RangedDebug<MIN, MAX>
2260{
2261    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2262        #[cfg(not(debug_assertions))]
2263        {
2264            let val = self.rint.get_unchecked();
2265            if <ri128<MIN, MAX>>::contains(val) {
2266                val.fmt(f)
2267            } else {
2268                write!(f, "#{val:?} [out of range: {MIN}..={MAX}]#")
2269            }
2270        }
2271        #[cfg(debug_assertions)]
2272        {
2273            let val = self.rint.get_unchecked();
2274            let min = self.rint.min;
2275            let max = self.rint.max;
2276            if <ri128<MIN, MAX>>::contains(val)
2277                && <ri128<MIN, MAX>>::contains(min)
2278                && <ri128<MIN, MAX>>::contains(max)
2279            {
2280                val.fmt(f)
2281            } else {
2282                write!(
2283                    f,
2284                    "#{val:?} \
2285                     [out of range: {MIN}..={MAX}] \
2286                     [possible range: {min}..={max}]#",
2287                )
2288            }
2289        }
2290    }
2291}
2292
2293/// A trait for losslessly converting between ranged integers.
2294///
2295/// This trait exists despite the fact that the standard library `From` trait
2296/// is defined in precisely the same way. Indeed, the `From` trait _almost_
2297/// works for our use case. The problem arises from the fact that we want
2298/// to be able to write this trait impl:
2299///
2300/// ```ignore
2301/// impl<
2302///     const MIN1: i128,
2303///     const MAX1: i128,
2304///     const MIN2: i128,
2305///     const MAX2: i128,
2306/// > From<ri64<MIN1, MAX1>> for ri64<MIN2, MAX2> {
2307/// // ...
2308/// }
2309/// ```
2310///
2311/// (We want this impl because we want to be able to freely convert between any
2312/// kind of ranged integers, including ranged integers with the same primitive
2313/// representation but different bounds.)
2314///
2315/// But this trait impl can't exist because it overlaps with the blanket
2316/// `impl From<T> for T`. Indeed, here, we do not provide that blanket impl,
2317/// which lets us add the trait impl above for `RFrom`.
2318///
2319/// This would normally be a no-go because it's too important for library
2320/// crates to provide types that work with `From` as you might expect, but
2321/// range integers are thankfully a crate internal abstraction. So we just need
2322/// to write `impl RFrom<T>` and do `t.rinto()` instead of `impl From<T>` and
2323/// `t.into()`.
2324pub(crate) trait RFrom<T>: Sized {
2325    fn rfrom(value: T) -> Self;
2326}
2327
2328/// A trait for losslessly converting to ranged integers.
2329///
2330/// This goes along with `RFrom` and exists to make things like `t.rinto()`
2331/// work without the need to do `T::rfrom(..)`. Like the standard library
2332/// `Into` trait, a blanket impl is provided based on impls of `RFrom`. Callers
2333/// are not expected to implement this trait directly.
2334pub(crate) trait RInto<T>: Sized {
2335    fn rinto(self) -> T;
2336}
2337
2338impl<T, U> RInto<U> for T
2339where
2340    U: RFrom<T>,
2341{
2342    fn rinto(self) -> U {
2343        RFrom::rfrom(self)
2344    }
2345}
2346
2347pub(crate) trait TryRFrom<T>: Sized {
2348    fn try_rfrom(what: &'static str, value: T) -> Result<Self, Error>;
2349}
2350
2351pub(crate) trait TryRInto<T>: Sized {
2352    fn try_rinto(self, what: &'static str) -> Result<T, Error>;
2353}
2354
2355impl<T, U> TryRInto<U> for T
2356where
2357    U: TryRFrom<T>,
2358{
2359    #[inline]
2360    fn try_rinto(self, what: &'static str) -> Result<U, Error> {
2361        U::try_rfrom(what, self)
2362    }
2363}
2364
2365#[cfg(test)]
2366mod tests {
2367    // use super::*;
2368
2369    // What follows below are some tests I wrote for my attempt at implementing
2370    // Ada-style modular/cyclic arithmetic on ranged integers. I found it to
2371    // be incredibly challenging. I decided that I could make do with only
2372    // using wrapping arithmetic on primitive-ranged integers and gave up.
2373    //
2374    // I did briefly look at GNAT to see if it could be of help, but I found
2375    // the source overwhelming and didn't find anything. I also could find any
2376    // help on the broader web for how to implement this correctly.
2377    //
2378    // Probably the next step here is to sit down with a pen & paper and work
2379    // out how this should be done, assuming we need/want it. One thing I ran
2380    // into was doing modular arithmetic when the range was bigger than the
2381    // underlying primitive representation. I could see how to do it if we
2382    // allowed casting up to a bigger integer representation, but I really
2383    // wanted to avoid doing that.
2384    /*
2385    type PrimitiveInt = ri8<{ i8::MIN as i128 }, { i8::MAX as i128 }>;
2386    type SmallInt = ri8<-20, 20>;
2387    type AlmostPrimitiveInt =
2388        ri8<{ i8::MIN as i128 }, { (i8::MAX - 1) as i128 }>;
2389
2390    #[test]
2391    fn wrapping_add_small() {
2392        let int = |n| SmallInt::new(n).unwrap();
2393
2394        assert_eq!(int(15).wrapping_add(int(5)), 20);
2395        assert_eq!(int(15).wrapping_add(int(6)), -20);
2396        assert_eq!(int(15).wrapping_add(int(-6)), 9);
2397        assert_eq!(int(-5).wrapping_add(int(5)), 0);
2398        assert_eq!(int(-5).wrapping_add(int(6)), 1);
2399        assert_eq!(int(-5).wrapping_add(int(3)), -2);
2400        assert_eq!(int(-5).wrapping_add(int(-3)), -8);
2401        assert_eq!(int(-5).wrapping_add(int(-13)), -18);
2402        assert_eq!(int(-5).wrapping_add(int(-15)), -20);
2403        assert_eq!(int(-5).wrapping_add(int(-16)), 20);
2404
2405        // These tests get SmallInts that are out-of-bounds (which is legal as
2406        // an intermediate value) and then try to do wrapping arithmetic on
2407        // them.
2408        let a: SmallInt = PrimitiveInt::new(127).unwrap();
2409        assert_eq!(a.wrapping_add(int(1)), 5);
2410        let a: SmallInt = PrimitiveInt::new(-128).unwrap();
2411        assert_eq!(a.wrapping_add(int(-1)), -6);
2412
2413        let a: SmallInt = PrimitiveInt::new(127).unwrap();
2414        let b: SmallInt = PrimitiveInt::new(127).unwrap();
2415        assert_eq!(a.wrapping_add(b), 8);
2416
2417        let a: SmallInt = PrimitiveInt::new(-128).unwrap();
2418        let b: SmallInt = PrimitiveInt::new(-128).unwrap();
2419        assert_eq!(a.wrapping_add(b), -10);
2420
2421        let a: SmallInt = PrimitiveInt::new(127).unwrap();
2422        let b: SmallInt = PrimitiveInt::new(-128).unwrap();
2423        assert_eq!(a.wrapping_add(b), -1);
2424
2425        let a: SmallInt = PrimitiveInt::new(-128).unwrap();
2426        let b: SmallInt = PrimitiveInt::new(127).unwrap();
2427        assert_eq!(a.wrapping_add(b), -1);
2428    }
2429
2430    #[test]
2431    fn wrapping_add_almost_primitive() {
2432        let int = |n| AlmostPrimitiveInt::new(n).unwrap();
2433
2434        assert_eq!(int(126).wrapping_add(int(126)), 0);
2435    }
2436
2437    quickcheck::quickcheck! {
2438        fn prop_wrapping_add_always_in_bounds(
2439            n1: SmallInt,
2440            n2: SmallInt
2441        ) -> bool {
2442            let sum = n1.wrapping_add(n2).get();
2443            SmallInt::contains(sum)
2444        }
2445
2446        fn prop_wrapping_add_always_in_bounds_primitive(
2447            n1: PrimitiveInt,
2448            n2: PrimitiveInt
2449        ) -> bool {
2450            let sum = n1.wrapping_add(n2).get();
2451            PrimitiveInt::contains(sum)
2452        }
2453    }
2454    */
2455}