I have a type OrderedVecSet
which is a transparent wrapper around Vec<T>
:
#[repr(transparent)]
struct OrderedVecSet<T>(Vec<T>)
where
T: Ord;
It obviously has the same layout as Vec<T>
, but with the library-level guarantee that the elements are in ascending order and without duplicates.
Since I want to use Rc<OrderedVecSet>
a lot, I would like an unsized version to reduce the number of indirections:
#[repr(transparent)]
struct OrderedVecSetUnsized<T>([T])
where
T: Ord;
I'm struggling to work out how to convert between OrderedVecSet<T>
and Rc<OrderedVecSetUnsized<T>>
using only safe Rust. My current implementation is below, but uses std::mem::transmute
, which I would like to avoid if possible. Also, as I understand it, the version below reuses the original allocation, and I would like to keep it that way.
use std::mem;
use std::rc::Rc;
impl<T> OrderedVecSetUnsized<T>
where
T: Ord,
{
fn from_slice_unchecked(slice: Rc<[T]>) -> Rc<Self> {
// SAFETY: OrderedVecSetUnsized is a transparent wrapper around a slice.
// (Actually, this is not safe.)
unsafe { mem::transmute(slice) }
}
}
impl<T> From<OrderedVecSet<T>> for Rc<OrderedVecSetUnsized<T>>
where
T: Ord,
{
fn from(set: OrderedVecSet<T>) -> Self {
let rc: Rc<[T]> = set.0.into();
OrderedVecSetUnsized::from_slice_unchecked(rc)
}
}
Can it be done in safe Rust? (Stable Rust is preferred, but if necessary, solutions requiring unstable are also fine.)