Fortune for rsh's current commit: Blessing − 吉master
parent
3a5331b5f1
commit
3991d82f93
@ -0,0 +1,91 @@
|
||||
//! Stack allocation helpers
|
||||
use super::*;
|
||||
|
||||
/// Max size of memory allowed to be allocated on the stack.
|
||||
pub const STACK_MEM_ALLOC_MAX: usize = 2048; // 2KB
|
||||
|
||||
/// A stack-allocated vector that spills onto the heap when needed.
|
||||
pub type StackVec<T> = SmallVec<[T; STACK_MEM_ALLOC_MAX]>;
|
||||
|
||||
/// Allocate a local buffer initialised from `init`.
|
||||
pub fn alloc_local_with<T, U>(sz: usize, init: impl FnMut() -> T, within: impl FnOnce(&mut [T]) -> U) -> U
|
||||
{
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory: Vec<T> = iter::repeat_with(init).take(sz).collect();
|
||||
within(&mut memory[..])
|
||||
} else {
|
||||
stackalloc::stackalloc_with(sz, init, within)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Allocate a local zero-initialised byte buffer
|
||||
pub fn alloc_local_bytes<U>(sz: usize, within: impl FnOnce(&mut [u8]) -> U) -> U
|
||||
{
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory: Vec<MaybeUninit<u8>> = vec_uninit(sz);
|
||||
within(unsafe {
|
||||
std::ptr::write_bytes(memory.as_mut_ptr(), 0, sz);
|
||||
stackalloc::helpers::slice_assume_init_mut(&mut memory[..])
|
||||
})
|
||||
} else {
|
||||
stackalloc::alloca_zeroed(sz, within)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Allocate a local zero-initialised buffer
|
||||
pub fn alloc_local_zeroed<T, U>(sz: usize, within: impl FnOnce(&mut [MaybeUninit<T>]) -> U) -> U
|
||||
{
|
||||
let sz_bytes = mem::size_of::<T>() * sz;
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory = vec_uninit(sz);
|
||||
unsafe {
|
||||
std::ptr::write_bytes(memory.as_mut_ptr(), 0, sz_bytes);
|
||||
}
|
||||
within(&mut memory[..])
|
||||
} else {
|
||||
stackalloc::alloca_zeroed(sz_bytes, move |buf| {
|
||||
unsafe {
|
||||
debug_assert_eq!(buf.len() / mem::size_of::<T>(), sz);
|
||||
within(std::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut MaybeUninit<T>, sz))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Allocate a local uninitialised buffer
|
||||
pub fn alloc_local_uninit<T, U>(sz: usize, within: impl FnOnce(&mut [MaybeUninit<T>]) -> U) -> U
|
||||
{
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory = vec_uninit(sz);
|
||||
within(&mut memory[..])
|
||||
} else {
|
||||
stackalloc::stackalloc_uninit(sz, within)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Allocate a local buffer initialised with `init`.
|
||||
pub fn alloc_local<T: Clone, U>(sz: usize, init: T, within: impl FnOnce(&mut [T]) -> U) -> U
|
||||
{
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory: Vec<T> = iter::repeat(init).take(sz).collect();
|
||||
within(&mut memory[..])
|
||||
} else {
|
||||
stackalloc::stackalloc(sz, init, within)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate a local buffer initialised with `T::default()`.
|
||||
pub fn alloc_local_with_default<T: Default, U>(sz: usize, within: impl FnOnce(&mut [T]) -> U) -> U
|
||||
{
|
||||
if sz > STACK_MEM_ALLOC_MAX {
|
||||
let mut memory: Vec<T> = iter::repeat_with(Default::default).take(sz).collect();
|
||||
within(&mut memory[..])
|
||||
} else {
|
||||
stackalloc::stackalloc_with_default(sz, within)
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
use std::{
|
||||
mem,
|
||||
iter::{
|
||||
self,
|
||||
ExactSizeIterator,
|
||||
FusedIterator,
|
||||
},
|
||||
slice,
|
||||
fmt,
|
||||
};
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HexStringIter<I>(I, [u8; 2]);
|
||||
|
||||
impl<I: Iterator<Item = u8>> HexStringIter<I>
|
||||
{
|
||||
/// Write this hex string iterator to a formattable buffer
|
||||
pub fn consume<F>(self, f: &mut F) -> fmt::Result
|
||||
where F: std::fmt::Write
|
||||
{
|
||||
if self.1[0] != 0 {
|
||||
write!(f, "{}", self.1[0] as char)?;
|
||||
}
|
||||
if self.1[1] != 0 {
|
||||
write!(f, "{}", self.1[1] as char)?;
|
||||
}
|
||||
|
||||
for x in self.0 {
|
||||
write!(f, "{:02x}", x)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Consume into a string
|
||||
pub fn into_string(self) -> String
|
||||
{
|
||||
let mut output = match self.size_hint() {
|
||||
(0, None) => String::new(),
|
||||
(_, Some(x)) |
|
||||
(x, None) => String::with_capacity(x),
|
||||
};
|
||||
self.consume(&mut output).unwrap();
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HexStringIterExt<I>: Sized
|
||||
{
|
||||
fn into_hex(self) -> HexStringIter<I>;
|
||||
}
|
||||
|
||||
pub type HexStringSliceIter<'a> = HexStringIter<iter::Copied<slice::Iter<'a, u8>>>;
|
||||
|
||||
pub trait HexStringSliceIterExt
|
||||
{
|
||||
fn hex(&self) -> HexStringSliceIter<'_>;
|
||||
}
|
||||
|
||||
impl<S> HexStringSliceIterExt for S
|
||||
where S: AsRef<[u8]>
|
||||
{
|
||||
fn hex(&self) -> HexStringSliceIter<'_>
|
||||
{
|
||||
self.as_ref().iter().copied().into_hex()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: IntoIterator<Item=u8>> HexStringIterExt<I::IntoIter> for I
|
||||
{
|
||||
#[inline] fn into_hex(self) -> HexStringIter<I::IntoIter> {
|
||||
HexStringIter(self.into_iter(), [0u8; 2])
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = u8>> Iterator for HexStringIter<I>
|
||||
{
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
match self.1 {
|
||||
[_, 0] => {
|
||||
use std::io::Write;
|
||||
write!(&mut self.1[..], "{:02x}", self.0.next()?).unwrap();
|
||||
|
||||
Some(mem::replace(&mut self.1[0], 0) as char)
|
||||
},
|
||||
[0, _] => Some(mem::replace(&mut self.1[1], 0) as char),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let (l, h) = self.0.size_hint();
|
||||
|
||||
(l * 2, h.map(|x| x*2))
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = u8> + ExactSizeIterator> ExactSizeIterator for HexStringIter<I>{}
|
||||
impl<I: Iterator<Item = u8> + FusedIterator> FusedIterator for HexStringIter<I>{}
|
||||
|
||||
impl<I: Iterator<Item = u8>> From<HexStringIter<I>> for String
|
||||
{
|
||||
fn from(from: HexStringIter<I>) -> Self
|
||||
{
|
||||
from.into_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = u8> + Clone> fmt::Display for HexStringIter<I>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
self.clone().consume(f)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[macro_export] macro_rules! prog1 {
|
||||
($first:expr, $($rest:expr);+ $(;)?) => {
|
||||
($first, $( $rest ),+).0
|
||||
}
|
||||
}
|
||||
*/
|
Loading…
Reference in new issue