// Copyright © 2024 Mikhail Hogrefe
//
// This file is part of Malachite.
//
// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
// 3 of the License, or (at your option) any later version. See .
use itertools::Itertools;
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom};
use malachite_base::num::exhaustive::exhaustive_signed_range;
use std::panic::catch_unwind;
fn expected_range_len(a: T, b: T) -> usize
where
usize: WrappingFrom,
{
usize::wrapping_from(b).wrapping_sub(usize::wrapping_from(a))
}
fn exhaustive_signed_range_helper_helper(a: T, b: T, values: &[i8])
where
i8: ExactFrom,
usize: WrappingFrom,
{
let xs = exhaustive_signed_range::(a, b)
.map(i8::exact_from)
.take(20)
.collect_vec();
assert_eq!(xs, values);
if T::WIDTH <= u16::WIDTH {
assert_eq!(
exhaustive_signed_range(a, b).count(),
expected_range_len(a, b)
);
}
}
fn exhaustive_signed_range_rev_helper(a: T, b: T, rev_values: &[T])
where
usize: WrappingFrom,
{
let len = expected_range_len(a, b);
assert_eq!(exhaustive_signed_range(a, b).count(), len);
let mut tail = exhaustive_signed_range::(a, b)
.skip(len.saturating_sub(20))
.collect_vec();
tail.reverse();
assert_eq!(tail, rev_values);
}
fn exhaustive_signed_range_helper()
where
i8: ExactFrom,
usize: WrappingFrom,
{
exhaustive_signed_range_helper_helper(T::ZERO, T::ZERO, &[]);
exhaustive_signed_range_helper_helper(T::ZERO, T::ONE, &[0]);
exhaustive_signed_range_helper_helper(
T::ZERO,
T::exact_from(10),
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
);
exhaustive_signed_range_helper_helper(
T::exact_from(10),
T::exact_from(20),
&[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
);
exhaustive_signed_range_helper_helper(
T::ZERO,
T::MAX,
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
);
exhaustive_signed_range_helper_helper(
T::ZERO,
T::MAX - T::ONE,
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
);
exhaustive_signed_range_helper_helper(
T::exact_from(-20),
T::exact_from(-10),
&[-11, -12, -13, -14, -15, -16, -17, -18, -19, -20],
);
exhaustive_signed_range_helper_helper(
T::exact_from(-100),
T::exact_from(100),
&[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10],
);
exhaustive_signed_range_helper_helper(
T::MIN,
T::MAX,
&[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10],
);
exhaustive_signed_range_helper_helper(
T::MIN + T::ONE,
T::MAX - T::ONE,
&[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10],
);
}
#[test]
fn test_exhaustive_signed_range() {
apply_fn_to_signeds!(exhaustive_signed_range_helper);
exhaustive_signed_range_rev_helper::(
i8::MIN,
i8::MAX,
&[
-128, -127, -126, 126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120,
120, -119, 119, -118, 118,
],
);
exhaustive_signed_range_rev_helper::(
i8::MIN + 1,
i8::MAX - 1,
&[
-127, -126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120, 120, -119,
119, -118, 118, -117, 117,
],
);
exhaustive_signed_range_rev_helper::(
i16::MIN,
i16::MAX,
&[
-32768, -32767, -32766, 32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762,
32762, -32761, 32761, -32760, 32760, -32759, 32759, -32758, 32758,
],
);
exhaustive_signed_range_rev_helper::(
i16::MIN + 1,
i16::MAX - 1,
&[
-32767, -32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762, 32762, -32761,
32761, -32760, 32760, -32759, 32759, -32758, 32758, -32757, 32757,
],
);
}
fn exhaustive_signed_range_fail_helper() {
assert_panic!(exhaustive_signed_range::(T::ONE, T::ZERO));
}
#[test]
fn exhaustive_signed_range_fail() {
apply_fn_to_signeds!(exhaustive_signed_range_fail_helper);
}