devela/data/sort/primitives.rs
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
// devela::data::sort::impl_primitives
//
//! Implements compile-time sorting algorithms for arrays of primitives.
//
#[cfg(_sort_float··)]
use crate::Compare;
use crate::{cfor, cswap, iif, paste, Sort};
/* impl Sort on primitives */
#[cfg(_sort··)]
macro_rules! impl_sort {
() => {
impl_sort![signed i8:"_sort_i8", i16:"_sort_i16", i32:"_sort_i32",
i64:"_sort_i64", i128:"_sort_i128", isize:"_sort_isize"];
impl_sort![unsigned u8:"_sort_u8", u16:"_sort_u16", u32:"_sort_u32",
u64:"_sort_u64", u128:"_sort_u128", usize:"_sort_usize"];
impl_sort![float f32:"_sort_f32", f64:"_sort_f64"];
};
// $t: the input/output primitive type
(signed $( $t:ty : $cap:literal ),+) => { $( impl_sort![@signed $t:$cap]; )+ };
(unsigned $( $t:ty : $cap:literal ),+) => { $( impl_sort![@unsigned $t:$cap]; )+ };
(float $( $t:ty : $cap:literal ),+) => { $( impl_sort![@float $t:$cap]; )+ };
(@signed $t:ty : $cap:literal) => { paste! {
/// Implement const sorting methods for arrays of primitives.
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
#[cfg(feature = $cap)]
impl<const N: usize> Sort<[$t; N]> {
/// Returns a copied sorted array using bubble sort.
#[must_use]
pub const fn bubble_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N => {
cfor![j in 0..N-i-1 => {
iif![arr[j] > arr[j+1]; cswap!(xor arr[j], arr[j+1])];
}];
}];
arr
}
/// Returns a copied sorted array using insertion sort.
#[must_use]
pub const fn insertion_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 1..N => {
let mut j = i;
while j > 0 && arr[j-1] > arr[j] {
cswap!(xor arr[j], arr[j-1]);
j -= 1;
}
}];
arr
}
/// Returns a copied sorted array using insertion sort.
#[must_use]
pub const fn selection_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N-1 => {
let mut min_index = i;
cfor![j in (i+1)..N => {
iif![arr[j] < arr[min_index]; min_index = j];
}];
cswap!(xor arr[min_index], arr[i]);
}];
arr
}
}
}};
(@unsigned $t:ty : $cap:literal) => { paste! {
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
#[cfg(feature = $cap)]
impl<const N: usize> Sort<[$t; N]> {
/// Returns a copied sorted array using bubble sort.
#[must_use]
pub const fn bubble_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N => {
cfor![j in 0..N-i-1 => {
iif![arr[j] > arr[j+1]; cswap!(xor arr[j], arr[j+1])];
}];
}];
arr
}
/// Returns a copied sorted array using insertion sort.
#[must_use]
pub const fn insertion_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 1..N => {
let mut j = i;
while j > 0 && arr[j-1] > arr[j] {
cswap!(xor arr[j], arr[j-1]);
j -= 1;
}
}];
arr
}
/// Returns a copied sorted array using selection sort.
#[must_use]
pub const fn selection_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N-1 => {
let mut min_index = i;
cfor![j in (i+1)..N => {
iif![arr[j] < arr[min_index]; min_index = j];
}];
cswap!(xor arr[min_index], arr[i]);
}];
arr
}
}
}};
(@float $t:ty : $cap:literal) => { paste! {
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
#[cfg(feature = $cap)]
impl<const N: usize> Sort<[$t; N]> {
/// Returns a copied sorted array using bubble sort.
#[must_use]
pub const fn bubble_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N => {
cfor![j in 0..N-i-1 => {
iif![Compare(arr[j]).gt(arr[j+1]); cswap!(arr[j], arr[j+1])];
}];
}];
arr
}
/// Returns a copied sorted array using insertion sort.
#[must_use]
pub const fn insertion_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 1..N => {
let mut j = i;
while j > 0 && Compare(arr[j-1]).gt(arr[j]) {
cswap!(arr[j], arr[j-1]);
j -= 1;
}
}];
arr
}
/// Returns a copied sorted array using selection sort.
#[must_use]
pub const fn selection_array(self) -> [$t; N] {
let mut arr = self.0;
cfor![i in 0..N-1 => {
let mut min_index = i;
cfor![j in (i+1)..N => {
iif![Compare(arr[j]).lt(arr[min_index]); min_index = j];
}];
cswap!(arr[min_index], arr[i]);
}];
arr
}
}
}};
}
#[cfg(_sort··)]
impl_sort![];