use super::ZeroBufInner;
use std::mem;
use std::ptr;
#[derive(Copy, Clone, Debug, Hash)]
pub struct DefaultParams;
pub trait Params<T> {
fn drop(&mut self, b: &mut [T]) {
DropYes.drop(b)
}
fn next_capacity(&mut self, b: &mut ZeroBufInner<T>) -> usize {
GrowMixed.next_capacity(b)
}
}
impl<T> Params<T> for DefaultParams {}
pub struct DropYes;
pub struct DropNo;
impl<T> Params<T> for DropYes {
fn drop(&mut self, b: &mut [T]) {
unsafe {
ptr::drop_in_place(&mut b[..]);
}
}
}
impl<T> Params<T> for DropNo {
fn drop(&mut self, _: &mut [T]) {
}
}
pub struct GrowMixed;
pub struct GrowDouble;
pub struct GrowOneAndAHalf;
impl<T> Params<T> for GrowMixed {
fn next_capacity(&mut self, b: &mut ZeroBufInner<T>) -> usize {
let size_of_t = usize::max(mem::size_of::<T>(), 1);
match b.capacity() {
0 => 1,
x if x < 4096 / size_of_t => x * 2,
x if x > 4096 * 32 / size_of_t => x * 2,
x => (x * 3 + 1) / 2,
}
}
}
impl<T> Params<T> for GrowDouble {
fn next_capacity(&mut self, b: &mut ZeroBufInner<T>) -> usize {
match b.capacity() {
0 => 1,
x => x * 2,
}
}
}
impl<T> Params<T> for GrowOneAndAHalf {
fn next_capacity(&mut self, b: &mut ZeroBufInner<T>) -> usize {
match b.capacity() {
0 => 1,
x => (x * 3 + 1) / 2,
}
}
}