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