I am implementing an alternative to a BTreeMap<K, V>. On top of this I'm building a BTreeSet, which is a wrapper around type MyBTreeSetContents<T> = MyBTreeMap<T, ()>.
Internally, leaf nodes of this BTree contain a Vec<(K, V)> of values.
In the case of the BTreeSet, this thus becomes a Vec<(K, ())>.
I want to provide a fast iterator over references of the values in the BTreeSet. An iterator that produces &T. But the best I can get so far without reaching for transmute is an iterator that produces &(T, ()).
So therefore the question:
- Is the memory representation of
K,(K, )and(K, ())the same? - Is it therefore OK to transmute between
(K, ())andK? - And by extension, is it OK to transmute the
Vec<(K, ())>to aVec<K>?
If there are alternative approaches that circumvent usage of std::mem::transmute all-together, those would of course also be very much appreciated!
No. As far as what is currently enforced, transmuting
(T, ())toTis not guaranteed. Tuples use the default representation which does not imply anything about the layout beyond what is said in The Rust Reference. Only#[repr(transparent)]will guarantee layout compatibility.However, it will probably work and may eventually be guaranteed. From Structs and Tuples in the Unsafe Code Guidelines:
If my understanding of this is correct,
(K, ())has the equivalent layout toKand thus can be transmuted safely. However, that will not extend to transmutingVec<T>toVec<U>as mentioned in Transmutes from the Rustonomicon:Unfortunately, you should take this with a grain of salt. The Unsafe Code Guidelines is an effort to recommend what
unsafecode can rely on, but currently it only advertises itself as a work-in-progress and that any concrete additions to the language specification will be moved to the official Rust Reference. I say this "will probably work" because a facet of the guidelines is to document current behavior. But as of yet, no guarantee like this has been mentioned in the reference.