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
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(test), feature(lang_items))]
#[cfg(not(any(feature = "std", test)))]
extern crate core as std;
#[cfg(not(any(feature = "std", test)))]
#[macro_use]
extern crate std;
pub mod generate {
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/generate.rs"));
}
#[cfg(any(feature = "std", test))]
mod debug;
#[inline]
unsafe fn swap_unchecked<T, F>(slice: &mut [T], lhs: usize, rhs: usize, compare: F)
where
F: Fn(&T, &T) -> Ordering,
{
use std::ptr;
let ptr = slice.as_mut_ptr();
let lhs_ptr = ptr.offset(lhs as isize);
let rhs_ptr = ptr.offset(rhs as isize);
let lhs_ref = &*lhs_ptr;
let rhs_ref = &*rhs_ptr;
let is_ordered = compare(&lhs_ref, &rhs_ref) == Ordering::Less;
let min_ptr = (if is_ordered { lhs_ref } else { rhs_ref }) as *const T;
let max_ptr = (if is_ordered { rhs_ref } else { lhs_ref }) as *const T;
let min_val = ptr::read(min_ptr);
let max_val = ptr::read(max_ptr);
ptr::write(lhs_ptr, min_val);
ptr::write(rhs_ptr, max_val);
}
pub trait SortingNetworkTrait {
fn sort<T>(&self, slice: &mut [T])
where
T: Ord,
{
self.sort_by(slice, |lhs, rhs| lhs.cmp(rhs))
}
fn sort_by<T, F>(&self, slice: &mut [T], compare: F)
where
F: Fn(&T, &T) -> Ordering;
}
pub trait FixedSizeSortingNetwork {
fn order() -> usize;
fn width() -> usize {
1 << Self::order()
}
}
pub struct SortingNetwork;
impl SortingNetwork {
pub fn new() -> Self {
SortingNetwork
}
pub fn sort<T>(&self, slice: &mut [T])
where
T: Ord,
{
let len = slice.len();
let is_power_of_two = (len & (len - 1)) == 0;
assert!(is_power_of_two);
self.sort_internal(slice, 0, len);
}
fn sort_internal<T>(&self, slice: &mut [T], i: usize, n: usize)
where
T: Ord,
{
if n <= 1 {
return;
}
let m = n / 2;
self.sort_internal(slice, i, m);
self.sort_internal(slice, i + m, m);
self.merge(slice, i, n, 1);
}
fn merge<T>(&self, slice: &mut [T], i: usize, n: usize, interval: usize)
where
T: Ord,
{
let m = interval * 2;
if m >= n {
let i = i;
let j = i + interval;
if slice[i] > slice[j] {
slice.swap(i, j);
}
return;
}
self.merge(slice, i, n, m);
self.merge(slice, i + interval, n, m);
let mut i = i + interval;
while i + interval < n {
let j = i + interval;
if slice[i] > slice[j] {
slice.swap(i, j);
}
i += m;
}
}
}
#[derive(Clone, Copy)]
struct SortingNetwork1;
impl SortingNetwork1 {
#[inline]
pub fn new() -> Self {
SortingNetwork1
}
}
impl SortingNetworkTrait for SortingNetwork1 {
#[inline]
fn sort_by<T, F>(&self, _slice: &mut [T], _compare: F)
where
F: Fn(&T, &T) -> Ordering,
{
}
}
include!(concat!(env!("OUT_DIR"), "/generated.rs"));