Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/slice.rs
6939 views
1
use std::cmp::Ordering;
2
use std::mem::MaybeUninit;
3
use std::ops::Range;
4
5
pub trait SliceAble {
6
/// # Safety
7
/// no bound checks.
8
unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self;
9
10
fn slice(&self, range: Range<usize>) -> Self;
11
}
12
13
impl<T> SliceAble for &[T] {
14
unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self {
15
unsafe { self.get_unchecked(range) }
16
}
17
18
fn slice(&self, range: Range<usize>) -> Self {
19
self.get(range).unwrap()
20
}
21
}
22
23
pub trait Extrema<T> {
24
fn min_value(&self) -> Option<&T>;
25
fn max_value(&self) -> Option<&T>;
26
}
27
28
impl<T: PartialOrd> Extrema<T> for [T] {
29
fn min_value(&self) -> Option<&T> {
30
self.iter()
31
.min_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal))
32
}
33
34
fn max_value(&self) -> Option<&T> {
35
self.iter()
36
.max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal))
37
}
38
}
39
40
pub trait SortedSlice<T> {
41
fn is_sorted_ascending(&self) -> bool;
42
}
43
44
impl<T: PartialOrd + Copy> SortedSlice<T> for [T] {
45
fn is_sorted_ascending(&self) -> bool {
46
if self.is_empty() {
47
true
48
} else {
49
let mut previous = self[0];
50
let mut sorted = true;
51
52
// don't early stop or branch
53
// so it autovectorizes
54
for &v in &self[1..] {
55
sorted &= previous <= v;
56
previous = v;
57
}
58
sorted
59
}
60
}
61
}
62
63
pub trait Slice2Uninit<T> {
64
fn as_uninit(&self) -> &[MaybeUninit<T>];
65
}
66
67
impl<T> Slice2Uninit<T> for [T] {
68
#[inline]
69
fn as_uninit(&self) -> &[MaybeUninit<T>] {
70
unsafe { std::slice::from_raw_parts(self.as_ptr() as *const MaybeUninit<T>, self.len()) }
71
}
72
}
73
74
// Loads a u64 from the given byteslice, as if it were padded with zeros.
75
#[inline]
76
pub fn load_padded_le_u64(bytes: &[u8]) -> u64 {
77
let len = bytes.len();
78
if len >= 8 {
79
return u64::from_le_bytes(bytes[0..8].try_into().unwrap());
80
}
81
82
if len >= 4 {
83
let lo = u32::from_le_bytes(bytes[0..4].try_into().unwrap());
84
let hi = u32::from_le_bytes(bytes[len - 4..len].try_into().unwrap());
85
return (lo as u64) | ((hi as u64) << (8 * (len - 4)));
86
}
87
88
if len == 0 {
89
return 0;
90
}
91
92
let lo = bytes[0] as u64;
93
let mid = (bytes[len / 2] as u64) << (8 * (len / 2));
94
let hi = (bytes[len - 1] as u64) << (8 * (len - 1));
95
lo | mid | hi
96
}
97
98