Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //assert!(new_cap < usize::max_value() >> 8)
- use core::mem::ManuallyDrop;
- #[cfg(target_endian = "little")]
- const MAGIC_NUMBER: usize = 23;
- #[cfg(target_endian = "big")]
- const MAGIC_NUMBER: usize = 0;
- #[cfg(target_endian = "little")]
- #[repr(C)]
- #[derive(Clone, Debug)]
- struct HeapString {
- ptr: *mut u8,
- len: usize,
- cap: usize,
- }
- #[cfg(target_endian = "big")]
- #[repr(C)]
- #[derive(Clone, Debug)]
- struct HeapString {
- cap: usize,
- len: usize,
- ptr: *mut u8,
- }
- impl HeapString {
- fn new(ptr: *mut u8, len: usize, cap: usize) -> Self {
- Self {
- cap,
- len,
- ptr
- }
- }
- unsafe fn as_mut_vec(&mut self) -> ManuallyDrop<Vec<u8>> {
- ManuallyDrop::new(Vec::from_raw_parts(self.ptr, self.len, self.cap))
- }
- }
- impl Copy for HeapString {}
- #[repr(C)]
- union Buffer {
- heap_buffer: HeapString,
- fast_buffer: [u8; 24]
- }
- impl Buffer {
- fn in_place() -> Self {
- let mut fast_buffer = [0; 24];
- fast_buffer[MAGIC_NUMBER] = 23;
- Self {
- fast_buffer
- }
- }
- fn is_in_place(&self) -> bool {
- unsafe {
- self.fast_buffer[MAGIC_NUMBER] != 0
- }
- }
- unsafe fn remaining(&self) -> usize {
- self.fast_buffer[MAGIC_NUMBER] as usize
- }
- unsafe fn push_in_place(&mut self, byte: u8) {
- let remaining = self.remaining();
- assert!(remaining > 0);
- self.fast_buffer[MAGIC_NUMBER - remaining] = byte;
- self.fast_buffer[MAGIC_NUMBER] -= 1;
- }
- unsafe fn fast_buffer_as_slice(&self) -> &[u8] {
- &self.fast_buffer[..MAGIC_NUMBER]
- }
- }
- impl Buffer {
- fn in_heap(ptr: *mut u8, len: usize, cap: usize) -> Self {
- Self {
- heap_buffer: HeapString::new(ptr, len, cap)
- }
- }
- unsafe fn push_in_heap(&mut self, byte: u8) {
- let mut vec = self.heap_buffer.as_mut_vec();
- vec.push(byte);
- self.heap_buffer.len = vec.len();
- self.heap_buffer.cap = vec.capacity();
- self.heap_buffer.ptr = vec.as_mut_ptr();
- }
- }
- impl Buffer {
- unsafe fn as_slice(&self) -> &[u8] {
- if self.is_in_place() {
- &self.fast_buffer[..MAGIC_NUMBER]
- } else {
- unsafe {
- core::slice::from_raw_parts(self.heap_buffer.ptr, self.heap_buffer.len)
- }
- }
- }
- }
- struct Bstring {
- buffer: Buffer
- }
- impl Bstring {
- pub fn new() -> Self {
- Self {
- buffer: Buffer::in_place()
- }
- }
- pub fn push(&mut self, byte: u8) {
- if self.buffer.is_in_place() {
- unsafe { self.buffer.push_in_place(byte) }
- if !self.buffer.is_in_place() {
- let mut v = ManuallyDrop::new(Vec::with_capacity(24));
- v.extend_from_slice(unsafe { self.buffer.fast_buffer_as_slice() });
- let cap = v.capacity();
- let len = v.len();
- let ptr = v.as_mut_ptr();
- self.buffer = Buffer::in_heap(ptr, len, cap)
- }
- } else {
- unsafe { self.buffer.push_in_heap(byte) };
- }
- }
- }
- impl core::ops::Deref for Bstring {
- type Target = [u8];
- fn deref(&self) -> &Self::Target {
- unsafe { self.buffer.as_slice() }
- }
- }
- impl Drop for Bstring {
- fn drop(&mut self) {
- if self.buffer.is_in_place() {
- } else {
- unsafe {
- ManuallyDrop::into_inner(self.buffer.heap_buffer.as_mut_vec());
- }
- }
- }
- }
- fn main() {
- let mut s = Bstring::new();
- for b in 1..26 {
- s.push(b);
- }
- // let x: &[u8] = &s;
- // println!("{:?}", x);
- }
- // #[repr(C)]
- // struct Bstring {
- // len: usize,
- // capacity: usize,
- // buffer: Buffer,
- // }
- // impl Bstring {
- // pub fn new() -> Self {
- // Self {
- // buffer: Buffer::in_place(),
- // len: 0,
- // capacity: 0,
- // }
- // }
- // pub fn is_in_place(&self) -> bool {
- // self.len == 0
- // }
- // pub fn push(&mut self, b: u8) {
- // if self.is_in_place() {
- // unsafe {
- // self.buffer.push_in_place(b);
- // if self.buffer.is_full_in_place() {
- // let mut v = ManuallyDrop::new(Vec::with_capacity(24));
- // v.extend_from_slice(&self.buffer.buffer[..23]);
- // let len = v.len();
- // let capacity = v.capacity();
- // let ptr = v.as_mut_ptr();
- // self.len = len;
- // self.capacity = capacity;
- // self.buffer.ptr = ptr;
- // }
- // }
- // } else {
- // unsafe {
- // ManuallyDrop::new(Vec::from_raw_parts(self.buffer.ptr, self.len, self.capacity)).push(b)
- // }
- // }
- // }
- // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement