use std::raw::TraitObject;
use std::mem::transmute;
pub trait Taggable {
fn get_untagged(&self) -> Self where Self: Sized;
fn get_tag_bit0(&self) -> bool;
fn get_tag_bit1(&self) -> bool;
fn get_tag_bit2(&self) -> bool;
fn set_tag_bit0(&mut self);
fn set_tag_bit1(&mut self);
fn set_tag_bit2(&mut self);
}
impl<T> Taggable for *mut T {
fn get_untagged(&self) -> Self {
let self_usize: usize = unsafe { transmute(self) };
((self_usize >> 3) << 3) as *mut T
}
fn get_tag_bit0(&self) -> bool {
let self_usize: usize = unsafe { transmute(self) };
self_usize & 0b001 == 1
}
fn get_tag_bit1(&self) -> bool {
let self_usize: usize = unsafe { transmute(self) };
self_usize & 0b010 == 1
}
fn get_tag_bit2(&self) -> bool {
let self_usize: usize = unsafe { transmute(self) };
self_usize & 0b100 == 1
}
fn set_tag_bit0(&mut self) {
let self_usize: usize = unsafe { transmute(self.clone()) };
*self = (self_usize | 0b001) as *mut T;
}
fn set_tag_bit1(&mut self) {
let self_usize: usize = unsafe { transmute(self.clone()) };
*self = (self_usize | 0b010) as *mut T;
}
fn set_tag_bit2(&mut self) {
let self_usize: usize = unsafe { transmute(self.clone()) };
*self = (self_usize | 0b100) as *mut T;
}
}
impl Taggable for TraitObject {
fn get_untagged(&self) -> Self {
TraitObject {
data: self.data.get_untagged(),
vtable: self.vtable
}
}
fn get_tag_bit0(&self) -> bool {
self.data.get_tag_bit0()
}
fn get_tag_bit1(&self) -> bool {
self.data.get_tag_bit1()
}
fn get_tag_bit2(&self) -> bool {
self.data.get_tag_bit2()
}
fn set_tag_bit0(&mut self) {
self.data.set_tag_bit0();
}
fn set_tag_bit1(&mut self) {
self.data.set_tag_bit1();
}
fn set_tag_bit2(&mut self) {
self.data.set_tag_bit2();
}
}