Skip to content

Instantly share code, notes, and snippets.

@Lisoph
Created April 5, 2018 08:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lisoph/8d7f963ac324ef3771660bc9b841b86d to your computer and use it in GitHub Desktop.
Save Lisoph/8d7f963ac324ef3771660bc9b841b86d to your computer and use it in GitHub Desktop.
A struct which can store an object to raw memory and restore from it.
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