// 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); }