transmute point_split instead of using raw parts
This commit is contained in:
+11
-35
@@ -767,15 +767,13 @@ impl Beatmap {
|
|||||||
let mut prev_time = 0.0;
|
let mut prev_time = 0.0;
|
||||||
let mut empty = true;
|
let mut empty = true;
|
||||||
|
|
||||||
// `point_split` elements will have the lifetime of `buf`.
|
// `point_split` will be of type `Vec<&str>
|
||||||
// If it wasn't split into parts, the borrow checker would complain.
|
// with each element having its lifetime bound to `buf`.
|
||||||
// The ptr is cast to a `*const u8` so its lifetime is not bound to `buf`.
|
// To cirvumvent this, `point_split_raw` will contain
|
||||||
// At the end of this scope, the vec will be built one last time
|
// the actual `&str` elements transmuted into `usize`.
|
||||||
// so it can be dropped and thus deallocated.
|
let mut point_split_raw: Vec<usize> = Vec::new();
|
||||||
let mut point_split_ptr = Vec::new().as_mut_ptr() as *const u8;
|
|
||||||
let mut point_split_length = 0;
|
|
||||||
let mut point_split_capacity = 0;
|
|
||||||
|
|
||||||
|
// Buffer to re-use for all sliders
|
||||||
let mut vertices = Vec::new();
|
let mut vertices = Vec::new();
|
||||||
|
|
||||||
while read_line!(reader, buf)? != 0 {
|
while read_line!(reader, buf)? != 0 {
|
||||||
@@ -838,14 +836,9 @@ impl Beatmap {
|
|||||||
let mut end_idx = 0;
|
let mut end_idx = 0;
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
|
|
||||||
// SAFETY: Parts originate from an actual Vec and are updated each iteration
|
// SAFETY: `Vec<usize>` and `Vec<&str>` have the same size and layout.
|
||||||
let mut point_split = unsafe {
|
let point_split: &mut Vec<&str> =
|
||||||
Vec::from_raw_parts(
|
unsafe { mem::transmute(&mut point_split_raw) };
|
||||||
point_split_ptr as *mut &str,
|
|
||||||
point_split_length,
|
|
||||||
point_split_capacity,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
point_split.clear();
|
point_split.clear();
|
||||||
point_split.extend(control_point_iter);
|
point_split.extend(control_point_iter);
|
||||||
@@ -867,9 +860,8 @@ impl Beatmap {
|
|||||||
// * The start of the next segment is the index after the type descriptor.
|
// * The start of the next segment is the index after the type descriptor.
|
||||||
let end_point = point_split.get(end_idx + 1).copied();
|
let end_point = point_split.get(end_idx + 1).copied();
|
||||||
|
|
||||||
let slice = &point_split[start_idx..end_idx];
|
|
||||||
convert_points(
|
convert_points(
|
||||||
slice,
|
&point_split[start_idx..end_idx],
|
||||||
end_point,
|
end_point,
|
||||||
first,
|
first,
|
||||||
pos,
|
pos,
|
||||||
@@ -882,9 +874,8 @@ impl Beatmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if end_idx > start_idx {
|
if end_idx > start_idx {
|
||||||
let slice = &point_split[start_idx..end_idx];
|
|
||||||
convert_points(
|
convert_points(
|
||||||
slice,
|
&point_split[start_idx..end_idx],
|
||||||
None,
|
None,
|
||||||
first,
|
first,
|
||||||
pos,
|
pos,
|
||||||
@@ -893,11 +884,6 @@ impl Beatmap {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
point_split_ptr = point_split.as_mut_ptr() as *const u8;
|
|
||||||
point_split_length = point_split.len();
|
|
||||||
point_split_capacity = point_split.capacity();
|
|
||||||
mem::forget(point_split);
|
|
||||||
|
|
||||||
if control_points.is_empty() {
|
if control_points.is_empty() {
|
||||||
HitObjectKind::Circle
|
HitObjectKind::Circle
|
||||||
} else {
|
} else {
|
||||||
@@ -967,16 +953,6 @@ impl Beatmap {
|
|||||||
sort_unstable(&mut self.hit_objects);
|
sort_unstable(&mut self.hit_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct vec one last time so it gets deallocated.
|
|
||||||
// SAFETY: Parts originate from an actual Vec and are updated each iteration
|
|
||||||
let _ = unsafe {
|
|
||||||
Vec::from_raw_parts(
|
|
||||||
point_split_ptr as *mut &str,
|
|
||||||
point_split_length,
|
|
||||||
point_split_capacity,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(empty)
|
Ok(empty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user