@@ -6,6 +6,68 @@ fn align_constants() {
66 assert_eq ! ( Align :: EIGHT , Align :: from_bytes( 8 ) . unwrap( ) ) ;
77}
88
9+ #[ test]
10+ #[ should_panic( expected = "Value 299 is too big for Size(1 bytes)" ) ]
11+ fn wrapping_range_smallest_range_containing_size_mismatch ( ) {
12+ WrappingRange :: smallest_range_containing ( 200 ..300 , Size :: from_bytes ( 1 ) ) ;
13+ }
14+
15+ #[ test]
16+ fn wrapping_range_smallest_range_containing ( ) {
17+ #[ track_caller]
18+ fn check ( x : impl IntoIterator < Item = u128 > , bytes : u64 , start : u128 , end : u128 ) {
19+ assert_eq ! (
20+ WrappingRange :: smallest_range_containing( x, Size :: from_bytes( bytes) ) ,
21+ Some ( WrappingRange { start, end } ) ,
22+ ) ;
23+ }
24+
25+ assert_eq ! ( WrappingRange :: smallest_range_containing( [ ] , Size :: from_bytes( 1 ) ) , None ) ;
26+
27+ check ( [ 7 ] , 1 , 7 , 7 ) ;
28+ check ( [ 7 , 7 , 7 ] , 1 , 7 , 7 ) ;
29+
30+ check ( 0 ..=127 , 1 , 0 , 127 ) ;
31+ check ( ( 0 ..=127 ) . chain ( [ 255 ] ) , 1 , 255 , 127 ) ;
32+
33+ check ( ( -100 ..=100_i128 ) . map ( i128:: cast_unsigned) , 16 , ( -100_i128 ) . cast_unsigned ( ) , 100 ) ;
34+
35+ // A wraparound case that's not just "sort them as signed"
36+ check ( [ 10 , 100 , 160 , 220 ] , 1 , 100 , 10 ) ;
37+
38+ check ( [ 0 , 0xFF ] , 1 , 0xFF , 0 ) ;
39+ check ( [ 0 , 0xFF ] , 2 , 0 , 0xFF ) ;
40+ check ( [ 0 , 0xFFFF ] , 2 , 0xFFFF , 0 ) ;
41+ check ( [ 0 , 0xFFFF ] , 4 , 0 , 0xFFFF ) ;
42+ check ( [ 0 , 0xFFFFFFFF ] , 4 , 0xFFFFFFFF , 0 ) ;
43+ check ( [ 0 , 0xFFFFFFFF ] , 8 , 0 , 0xFFFFFFFF ) ;
44+
45+ check ( [ 100 , 200 ] , 1 , 100 , 200 ) ;
46+ check ( [ 100 , 200 , 50 ] , 1 , 50 , 200 ) ;
47+ check ( [ 100 , 200 , 250 ] , 1 , 100 , 250 ) ;
48+ check ( [ 100 , 200 , 250 , 50 ] , 1 , 200 , 100 ) ;
49+
50+ check ( [ 200 , 50 ] , 1 , 200 , 50 ) ;
51+ check ( [ 200 , 50 , 190 ] , 1 , 190 , 50 ) ;
52+ check ( [ 200 , 50 , 60 ] , 1 , 200 , 60 ) ;
53+ check ( [ 200 , 50 , 125 ] , 1 , 50 , 200 ) ;
54+
55+ // The mem::Alignment case
56+ check ( ( 0 ..64 ) . map ( |n| 1 << n) , 8 , 1 , i64:: MIN . cast_unsigned ( ) . into ( ) ) ;
57+
58+ // Both `100..=228` and `..=228 | 100..` are the same size, but we pick the one without zero.
59+ check ( [ 100 , 228 ] , 1 , 100 , 228 ) ;
60+
61+ // The wraparound one here is slightly smaller, so we pick it despite including zero.
62+ // (The distance 10→96 is 86, compared to 85 for 96→181 and 181→10.)
63+ check ( [ 10 , 96 , 181 ] , 1 , 96 , 10 ) ;
64+
65+ // These 4 values are evenly spaced so all 4 candidate ranges have length 193:
66+ // `(..=32) | (96..)`, `(..=96) | (160..)`, `(..=160) | (224..)`, and `32..=224`.
67+ // We pick the last one as the only one that doesn't contain zero.
68+ check ( [ 0xA0 , 0xE0 , 0x20 , 0x60 ] , 1 , 0x20 , 0xE0 ) ;
69+ }
70+
971#[ test]
1072fn wrapping_range_contains_range ( ) {
1173 let size16 = Size :: from_bytes ( 16 ) ;
0 commit comments