copyless
copyless copied to clipboard
Turn a Box into a BoxAllocation
It might be useful to be able to take an existing Box and turn it back into a BoxAllocation.
For example, you might want to use the same allocation twice like in this contrived example:
fn make_big_thing(box_alloc: BoxAllocation<Thing>) -> Box<Thing> {
box_alloc.init(...)
}
fn main() {
let box_alloc = BoxAllocation::init();
let thing = make_big_thing(box_alloc);
do_something_with_thing(&thing);
let box_alloc = BoxAllocation::from_box(thing);
let thing2 = make_big_thing(box_alloc);
do_something_with_thing(&thing2);
}
How would this be different from just overwriting the contents of the box you have, i.e.
let box_alloc = BoxAllocation::init();
let mut thing = make_big_thing(box_alloc);
do_something_with_thing(&thing);
*thing = <something>;
do_something_with_thing(&thing);
That example code doesn't call make_big_thing twice while mine does, so it misses the point. make_big_thing takes a BoxAllocation<Thing> because it wants an uninitialised space to put an instance of Thing. If you can't turn a Box back into a BoxAllocation, you would be required to make a brand new allocation each time that make_big_thing is called.
Could you make an example of what make_big_thing does that can't be expressed with my code sample?
Say I have some function that parses data about an animal from a file:
struct Animal {
age: u32,
weight: f32,
height: f32,
number_of_legs: u32,
a lot of other fields, making this a huge struct...
}
fn parse_animal_from_file(filename: String) -> Box<Animal> {
let file = open(filename);
let age = file.parse_age();
let weight = file.parse_weight();
...
BoxAllocation<Animal>::alloc().init(Animal {age, weight, height, etc.})
}
let dog_data = parse_animal_from_file("dog.txt");
print("{:?}", dog_data);
// Note that dog_data is no longer used past this point.
let cat_data = parse_animal_from_file("cat.txt");
print("{:?}", cat_data);
Then I decide I want to be able to reuse an allocation if possible if I already have one. Why not? So I rewrite it like so:
fn parse_animal_from_file(filename: String, box_alloc: BoxAllocation<Animal>) -> Box<Animal> {
let file = open(filename);
let age = file.parse_age();
let weight = file.parse_weight();
...
box_alloc.init(Animal {age, weight, height, etc.})
}
let box_alloc = BoxAllocation<Thing>::alloc();
let dog_data = parse_animal_from_file("dog.txt", box_alloc);
print("{:?}", dog_data);
let box_alloc = dog_data.turn_back_into_alloc();
let cat_data = parse_animal_from_file("cat.txt", box_alloc);
print("{:?}", cat_data);
But unfortunately this doesn't work because no such turn_back_into_alloc function exists.
It sounds like you could do this instead:
fn parse_animal_from_file(filename: String) -> Animal {
...
}
let dog_data = Box::alloc().init(parse_animal_from_file("dog.txt"));
print("{:?}", dog_data);
let mut cat_data = dog_data;
*cat_data = parse_animal_from_file("cat.txt");
print("{:?}", cat_data);
That would equally preserve the allocation, without the need to go back to BoxAllocation