1#![allow(dead_code)]
2
3pub use simd::Trend;
4
5use crate::simd::SinglePrecision;
6
7mod simd;
8
9pub 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}