1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! SIMD-accelerated radix sort for primitive types.
//!
//! `turbosort` provides O(n) LSD radix sort with SIMD acceleration for the 10
//! primitive numeric types: `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`,
//! `i64`, `f32`, `f64`.
//!
//! # Features
//!
//! - **`std`** (default): enables heap allocation for internal buffers.
//! - **`alloc`**: like `std` but for `no_std` + allocator environments.
//! - **`parallel`**: enables `sort_parallel()` via rayon for huge arrays.
//!
//! # Usage
//!
//! ```
//! let mut data = vec![5u32, 3, 8, 1, 9, 2, 7, 4, 6];
//! turbosort::sort(&mut data);
//! assert_eq!(data, vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
//! ```
//!
//! For allocation-sensitive code, use [`sort_with_buffer`]:
//!
//! ```
//! let mut data = [5u32, 3, 8, 1, 9];
//! let mut buf = [0u32; 5];
//! turbosort::sort_with_buffer(&mut data, &mut buf);
//! assert_eq!(data, [1, 3, 5, 8, 9]);
//! ```
extern crate alloc;
pub use SortableKey;
/// Sort a mutable slice of any [`SortableKey`] type in ascending order.
///
/// Automatically selects the optimal algorithm based on input size:
/// - n ≤ 16: sorting network
/// - 17 ≤ n ≤ 512: quicksort
/// - n > 512: LSD radix sort (requires `alloc` feature)
///
/// Without the `alloc` feature, arrays > 512 elements fall back to quicksort.
///
/// # Examples
///
/// ```
/// let mut v = vec![3i32, -1, 4, -1, 5, -9];
/// turbosort::sort(&mut v);
/// assert_eq!(v, vec![-9, -1, -1, 3, 4, 5]);
/// ```
///
/// ```
/// let mut v = vec![1.0f32, f32::NAN, -0.0, 0.0, f32::NEG_INFINITY];
/// turbosort::sort(&mut v);
/// assert_eq!(v[0], f32::NEG_INFINITY);
/// assert!(v[1].to_bits() == (-0.0f32).to_bits()); // -0.0 < +0.0
/// assert!(v[4].is_nan()); // NaN sorted to end
/// ```
/// Sort a mutable slice using a caller-provided buffer.
///
/// The buffer must be at least as long as the slice. This avoids internal
/// allocation, making it suitable for `no_std`, embedded, or latency-sensitive
/// contexts.
///
/// # Panics
///
/// Panics if `buffer.len() < slice.len()`.
///
/// # Examples
///
/// ```
/// let mut data = [42u64, 7, 99, 1, 0];
/// let mut buf = [0u64; 5];
/// turbosort::sort_with_buffer(&mut data, &mut buf);
/// assert_eq!(data, [0, 1, 7, 42, 99]);
/// ```
/// Sort a mutable slice using parallel LSD radix sort.
///
/// Uses rayon to distribute work across multiple cores. Falls back to
/// single-threaded radix sort for arrays below 131K elements.
///
/// Requires the `parallel` feature.
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "parallel")]
/// # {
/// let mut data: Vec<u32> = (0..1_000_000).rev().collect();
/// turbosort::sort_parallel(&mut data);
/// assert_eq!(data, (0..1_000_000).collect::<Vec<u32>>());
/// # }
/// ```