sorted_rs/
lib.rs

1#![allow(dead_code)]
2
3pub use simd::Trend;
4
5use crate::simd::SinglePrecision;
6
7mod simd;
8
9///
10/// example:
11///     let nums = vec![1, 2, 3, 4, 5, ....];
12///     is_sorted(&nums, Trend::Ascending);
13///     let nums = vec![9, 8, 7, 6, 5, ....];
14///     is_sorted(&nums, Trend:Descending);
15///
16/// is_sorted check sequence is sorted or not but it doesn't check the length of input.
17/// It's better to avoid call the function when the length of input is 1 or 0;
18
19pub fn is_sorted<T: num::Integer + SinglePrecision>(a: &[T], t: Trend) -> bool {
20    let a = a.as_ref();
21    let n = a.len();
22    #[cfg(feature = "use-sse")]
23    {
24        if n < SSE_WORD {
25            return simd::is_sorted(a, t);
26        }
27    }
28    #[cfg(feature = "use-avx2")]
29    {
30        if n < AVX2_WORD {
31            return simd::is_sorted(&a, t);
32        }
33    }
34    #[cfg(feature = "use-sse")]
35    {
36        if n >= SSE_WORD {
37            return simd::is_sorted_unroll4(&a, t);
38        }
39    }
40    #[cfg(feature = "use-avx2")]
41    {
42        if n >= AVX2_WORD {
43            return simd::is_sorted_unroll4(&a, t);
44        }
45    }
46    false
47}
48
49const WORD: usize = 8;
50const SSE_WORD: usize = 4 * (4 + 1);
51const AVX2_WORD: usize = 4 * 7 + 1;
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_works() {
59        for i in 1..1024 {
60            let mut a = (0..i).into_iter().collect::<Vec<_>>();
61            assert!(is_sorted(&a, Trend::Ascending));
62            a.reverse();
63            assert!(is_sorted(&a, Trend::Descending));
64            a.fill(1);
65            assert!(is_sorted(&a, Trend::Ascending));
66            assert!(is_sorted(&a, Trend::Descending));
67        }
68
69        for i in 6..1024 {
70            let a = (0..i).into_iter().collect::<Vec<_>>();
71            let mut reversed: Vec<i32> = Vec::with_capacity(a.len());
72            for cur_data in a.chunks(3) {
73                reversed.extend(cur_data.iter().rev());
74            }
75
76            assert!(!is_sorted(&reversed, Trend::Ascending), "{:?}", reversed);
77            assert!(!is_sorted(&reversed, Trend::Descending), "{:?}", reversed);
78        }
79
80        for i in 1u32..1024 {
81            let mut a = (0..i).into_iter().collect::<Vec<_>>();
82            assert!(is_sorted(&a, Trend::Ascending));
83            a.reverse();
84            assert!(is_sorted(&a, Trend::Descending));
85            a.fill(1);
86            assert!(is_sorted(&a, Trend::Ascending));
87            assert!(is_sorted(&a, Trend::Descending));
88        }
89    }
90}