Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use core::array::FixedSizeArray;
- use core::marker::Unsize;
- use core::ops::CoerceUnsized;
- use std::ptr;
- use std::mem;
- use std::ops::{Deref, DerefMut};
- pub struct Direct<T, B: FixedSizeArray<u8>> {
- ptr: *mut T,
- buffer: B
- }
- impl<T, B: FixedSizeArray<u8>> Direct<T, B> {
- pub fn new(elem: T) -> Self {
- unsafe {
- let mut direct = Direct::<T, B> {
- ptr: ptr::null_mut(),
- buffer: mem::uninitialized()
- };
- if mem::size_of::<T>() > direct.buffer.as_slice().len() {
- // it can't fit, so store it on the heap
- direct.ptr = Box::into_raw(Box::new(elem));
- } else {
- // it can fit, so move it into the buffer
- ptr::write(&mut direct.buffer.as_mut_slice()[0] as *mut u8 as *mut T, elem);
- }
- direct
- }
- }
- }
- impl<T, B: FixedSizeArray<u8>> Deref for Direct<T, B> {
- type Target = T;
- fn deref(&self) -> &<Self as Deref>::Target {
- unsafe {
- if self.ptr.is_null() {
- &*(&self.buffer.as_slice()[0] as *const u8 as *const T)
- } else {
- &*self.ptr
- }
- }
- }
- }
- impl<T, B: FixedSizeArray<u8>> DerefMut for Direct<T, B> {
- fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
- unsafe {
- if self.ptr.is_null() {
- &mut*(&mut self.buffer.as_mut_slice()[0] as *mut u8 as *mut T)
- } else {
- &mut*self.ptr
- }
- }
- }
- }
- impl<T, B: FixedSizeArray<u8>> Drop for Direct<T, B> {
- fn drop(&mut self) {
- unsafe {
- if self.ptr.is_null() {
- ptr::drop_in_place(&mut self.buffer.as_mut_slice()[0] as *mut u8 as *mut T);
- } else {
- mem::drop(Box::from_raw(self.ptr))
- }
- }
- }
- }
- #[cfg(test)]
- pub mod tests {
- use super::*;
- #[test]
- pub fn fat_ptr_large_test() {
- let mut arr = [0u8; 100];
- for i in 0..100 {
- arr[i] = i as u8;
- }
- let direct: Direct<[u8; 100], [u8; 20]> = Direct::new(arr.clone());
- for i in 0..100 {
- assert_eq!(arr[i], direct[i]);
- }
- }
- #[test]
- pub fn fat_ptr_small_test() {
- let mut arr = [0u8; 20];
- for i in 0..20 {
- arr[i] = i as u8;
- }
- let direct: Direct<[u8; 20], [u8; 100]> = Direct::new(arr.clone());
- for i in 0..20 {
- assert_eq!(arr[i], direct[i]);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement