Created
April 5, 2018 08:12
-
-
Save haudan/8d7f963ac324ef3771660bc9b841b86d to your computer and use it in GitHub Desktop.
A struct which can store an object to raw memory and restore from it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::marker::PhantomData; | |
#[derive(Clone)] | |
struct App { | |
data: Vec<String>, | |
data2: Tester, | |
} | |
#[derive(Clone)] | |
struct Tester; | |
impl Tester { | |
fn new() -> Self { | |
println!("New Tester"); | |
Tester | |
} | |
} | |
impl std::ops::Drop for Tester { | |
fn drop(&mut self) { | |
println!("Tester dropped!"); | |
} | |
} | |
struct Storage<T> { | |
data: Vec<u8>, | |
_m: PhantomData<T>, | |
} | |
impl<T: Clone> Storage<T> { | |
fn new() -> Self { | |
Self { | |
data: Vec::with_capacity(std::mem::size_of::<T>()), | |
_m: PhantomData, | |
} | |
} | |
fn store(&mut self, obj: &T) { | |
let size = std::mem::size_of::<T>(); | |
unsafe { | |
let line_obj = self.data.as_ptr() as *mut T; | |
std::ptr::write_unaligned(line_obj, obj.clone()); | |
// *line_obj = obj; | |
// let _ = std::mem::replace(&mut *line_obj, obj); | |
} | |
} | |
fn restore(&self) -> T { | |
unsafe { | |
let obj = &mut *(self.data.as_ptr() as *mut T); | |
// let mut new: T = std::mem::uninitialized(); | |
// let _ = std::mem::swap(&mut new, obj); | |
// new | |
obj.clone() | |
} | |
} | |
} | |
struct PseudoStorage<T> { | |
object: T, | |
} | |
impl<T> PseudoStorage<T> { | |
fn new() -> Self { | |
Self { | |
object: unsafe { std::mem::uninitialized() }, | |
} | |
} | |
fn store(&mut self, obj: T) { | |
unsafe { std::ptr::write(&mut self.object as *mut _, obj) }; | |
} | |
fn restore(&mut self) -> T { | |
unsafe { | |
// let self_obj = &mut *(&self.object as *const _ as *mut _); | |
let self_obj = &mut self.object; | |
let mut obj: T = std::mem::uninitialized(); | |
let _ = std::mem::swap(&mut obj, self_obj); | |
obj | |
} | |
} | |
} | |
impl<T> std::ops::Drop for PseudoStorage<T> { | |
fn drop(&mut self) { | |
// std::mem::forget(self.object); | |
} | |
} | |
fn main() { | |
let app = App { | |
data: vec!["Hello".to_owned(), "world!".to_owned()], | |
data2: Tester::new(), | |
}; | |
println!("String ptr: {:p}", app.data[0].as_ptr()); | |
let mut storage = Storage::new(); | |
storage.store(&app); | |
println!("Stored {} bytes.", storage.data.capacity()); | |
let app = storage.restore(); | |
println!("String ptr: {:p}", app.data[0].as_ptr()); | |
for s in app.data.iter() { | |
println!("{}", s); | |
} | |
println!("\n"); | |
let app = App { | |
data: vec!["hey".to_owned()], | |
data2: Tester::new(), | |
}; | |
println!("String ptr: {:p}", app.data[0].as_ptr()); | |
let mut pseudo = PseudoStorage::new(); | |
pseudo.store(app); | |
let app = pseudo.restore(); | |
println!("String ptr: {:p}", app.data[0].as_ptr()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment