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
#![no_std]
use core::{cmp::*, mem, ops::*, slice};
mod private {
pub trait OptionExtSealed {}
pub trait SliceExtSealed {}
}
use private::*;
pub trait OptionExt: OptionExtSealed {
type Inner;
fn try_get_or_insert_with<E, F: FnOnce() -> Result<Self::Inner, E>>(&mut self, f: F) -> Result<&mut Self::Inner, E>;
}
impl<A> OptionExtSealed for Option<A> {}
impl<A> OptionExt for Option<A> {
type Inner = A;
#[inline]
fn try_get_or_insert_with<E, F: FnOnce() -> Result<A, E>>(&mut self, f: F) -> Result<&mut A, E> { unsafe {
if let None = self { *self = Some(f()?) }
match self {
Some(a) => Ok(a),
_ => ::core::hint::unreachable_unchecked(),
}
} }
}
pub trait SliceExt: SliceExtSealed {
type Inner;
fn is_sorted(&self) -> bool where Self::Inner: Ord { self.is_sorted_by(Ord::cmp) }
fn is_sorted_by<F: FnMut(&Self::Inner, &Self::Inner) -> Ordering>(&self, f: F) -> bool;
fn is_sorted_by_key<F: FnMut(&Self::Inner) -> K, K: Ord>(&self, mut f: F) -> bool {
self.is_sorted_by(|a, b| Ord::cmp(&f(a), &f(b)))
}
fn try_split_at(&self, k: usize) -> Option<(&Self, &Self)>;
fn try_split_at_mut(&mut self, k: usize) -> Option<(&mut Self, &mut Self)>;
unsafe fn split_at_unchecked(&self, k: usize) -> (&Self, &Self);
unsafe fn split_at_unchecked_mut(&mut self, k: usize) -> (&mut Self, &mut Self);
unsafe fn copy_from_ptr(&mut self, _: *const Self::Inner);
fn copy_x(&mut self, s: usize, t: usize, n: usize) where Self::Inner: Copy;
fn copy_from_x(&mut self, other: &Self) where Self::Inner: Copy;
}
impl<A> SliceExtSealed for [A] {}
impl<A> SliceExt for [A] {
type Inner = A;
#[inline]
fn is_sorted_by<F: FnMut(&A, &A) -> Ordering>(&self, mut f: F) -> bool {
(1..self.len()).all(|k| Ordering::Less != f(&self[k], &self[k-1]))
}
#[inline]
fn try_split_at(&self, k: usize) -> Option<(&Self, &Self)> {
if k > self.len() { None } else { Some(unsafe { self.split_at_unchecked(k) }) }
}
#[inline]
fn try_split_at_mut(&mut self, k: usize) -> Option<(&mut Self, &mut Self)> {
if k > self.len() { None } else { Some(unsafe { self.split_at_unchecked_mut(k) }) }
}
#[inline(always)]
unsafe fn split_at_unchecked(&self, k: usize) -> (&Self, &Self) {
(slice::from_raw_parts(self.as_ptr(), k),
slice::from_raw_parts(self.as_ptr().add(k), self.len() - k))
}
#[inline(always)]
unsafe fn split_at_unchecked_mut(&mut self, k: usize) -> (&mut Self, &mut Self) {
(slice::from_raw_parts_mut(self.as_mut_ptr(), k),
slice::from_raw_parts_mut(self.as_mut_ptr().add(k), self.len() - k))
}
#[inline(always)]
unsafe fn copy_from_ptr(&mut self, ptr: *const Self::Inner) {
ptr.copy_to_nonoverlapping(self.as_mut_ptr(), self.len())
}
#[inline]
fn copy_x(&mut self, s: usize, t: usize, n: usize) where Self::Inner: Copy { self.copy_within(s..s + n, t) }
#[inline]
fn copy_from_x(&mut self, other: &Self) where Self::Inner: Copy { unsafe {
let l = core::cmp::min(self.len(), other.len());
core::ptr::copy_nonoverlapping(other.as_ptr(), self.as_mut_ptr(), l)
} }
}
#[inline]
pub fn checked_sub<A: PartialOrd<B> + Sub<B>, B>(a: A, b: B) -> Option<<A as Sub<B>>::Output> {
if a >= b { Some(a - b) } else { None }
}
#[inline]
pub fn zip_opt<A, B>(x: Option<A>, y: Option<B>) -> Option<(A, B)> {
match (x, y) {
(Some(x), Some(y)) => Some((x, y)),
_ => None,
}
}
#[inline(always)]
pub fn ptr_diff<A>(q: *mut A, p: *mut A) -> usize { (q as usize - p as usize)/mem::size_of::<A>() }