use std::mem;
use std::ptr;
use std::slice;
pub trait SafePtr {
type Ptr;
fn as_safe_ptr(&self) -> *const Self::Ptr;
}
impl<T> SafePtr for Vec<T> {
type Ptr = T;
fn as_safe_ptr(&self) -> *const T {
if self.is_empty() {
ptr::null()
} else {
self.as_ptr()
}
}
}
pub fn vec_into_raw_parts<T>(v: Vec<T>) -> (*mut T, usize) {
let mut b = v.into_boxed_slice();
let ptr = b.as_mut_ptr();
let len = b.len();
mem::forget(b);
(ptr, len)
}
pub unsafe fn vec_from_raw_parts<T>(ptr: *mut T, len: usize) -> Vec<T> {
Box::from_raw(slice::from_raw_parts_mut(ptr, len)).into_vec()
}
pub unsafe fn vec_clone_from_raw_parts<T: Clone>(ptr: *const T, len: usize) -> Vec<T> {
slice::from_raw_parts(ptr, len).to_vec()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vec_conversions() {
for _ in 0..5 {
let v = vec!["foo", "bar"];
for _ in 0..5 {
let (ptr, len) = vec_into_raw_parts(v.clone());
let v2 = unsafe { vec_clone_from_raw_parts(ptr, len) };
assert_eq!(v, v2);
let v3 = unsafe { vec_from_raw_parts(ptr, len) };
assert_eq!(v, v3);
}
}
}
}