Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(core_intrinsics)]
- #![feature(raw)]
- #![allow(unused_variables)]
- #![allow(dead_code)]
- use std::any::TypeId;
- use std::raw::TraitObject;
- pub trait AsDyn {
- fn __as_dyn<'a>(&'a self, id: TypeId) -> Option<TraitObject>;
- fn __as_dyn_mut<'a>(&'a mut self, target_type: TypeId) -> Option<TraitObject>;
- }
- impl AsDyn {
- pub fn as_dyn<'a, T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
- if let Some(trait_obj) = self.__as_dyn(TypeId::of::<T>()) {
- let value = unsafe {
- *(&trait_obj as *const TraitObject as *const &'a T)
- };
- Some(value)
- }
- else {
- None
- }
- }
- pub fn as_dyn_mut<'a, T: ?Sized + 'static>(&'a mut self) -> Option<&'a mut T> {
- if let Some(mut trait_obj) = self.__as_dyn_mut(TypeId::of::<T>()) {
- let value = {
- &mut trait_obj as *mut TraitObject as *mut &'a mut T
- };
- Some(unsafe { *value })
- }
- else {
- None
- }
- }
- }
- macro_rules! as_dyn {
- // Trait implementation
- (
- [$( $target_ty:ty ),*]
- impl<$($args:ident),* $(,)*> AsDyn for $type:ty
- where $( $preds:tt )+
- )
- => {
- impl<$( $args )*> AsDyn for $type
- where $($preds)*
- {
- fn __as_dyn<'a>(&'a self, id: std::any::TypeId) -> Option<std::raw::TraitObject> {
- $(
- as_dyn!(self, id, $target_ty);
- )*
- None
- }
- fn __as_dyn_mut<'a>(&'a mut self, id: std::any::TypeId) -> Option<std::raw::TraitObject> {
- $(
- as_dyn!(self, id, mut $target_ty);
- )*
- None
- }
- }
- };
- // Mutable implementation
- ($self:ident, $id:ident, mut $ty:ty) => {
- if $id == std::any::TypeId::of::<$ty>() {
- let trait_obj = unsafe {
- std::mem::transmute($self as &'a mut $ty)
- };
- return Some(trait_obj);
- }
- };
- // Immutable implementation
- ($self:ident, $id:ident, $ty:ty) => {
- if $id == std::any::TypeId::of::<$ty>() {
- let trait_obj = unsafe {
- std::mem::transmute($self as &'a $ty)
- };
- return Some(trait_obj);
- }
- };
- }
- trait A {
- fn run(&self) -> &'static str {
- "A"
- }
- }
- trait B {
- fn run(&self) -> &'static str {
- "B"
- }
- }
- trait C<T> {
- fn run(&self, _v: T) -> &'static str {
- "C<T>"
- }
- }
- trait D {
- fn run(&self) -> &'static str {
- "D"
- }
- }
- trait E<T> {
- fn run(&self, _v: T) -> &'static str {
- "E<T>"
- }
- }
- struct Implementor<T> {
- v: T
- }
- impl<T> A for Implementor<T> {}
- impl<T> B for Implementor<T> {}
- impl<T> C<T> for Implementor<T> {}
- impl<T> E<usize> for Implementor<T> {}
- as_dyn!(
- [ A, B, C<T>, E<usize> ]
- impl<T> AsDyn for Implementor<T>
- where T: 'static
- );
- fn main() {
- let mut i = Implementor { v: 0.0_f32 };
- let x: &mut dyn AsDyn = &mut i;
- let a = x.as_dyn::<A>();
- let b = x.as_dyn::<B>();
- let c = x.as_dyn::<C<f32>>();
- let d = x.as_dyn::<D>();
- let e = x.as_dyn::<E<usize>>();
- println!(
- "A: {}, B: {}, C: {}, D: {}, E: {}",
- opt_as_str(&a),
- opt_as_str(&b),
- opt_as_str(&c),
- opt_as_str(&d),
- opt_as_str(&e)
- );
- }
- fn opt_as_str<T>(opt: &Option<T>) -> &'static str {
- match opt {
- Some(_) => "Some",
- None => "None"
- }
- }
- /*
- fn main() {
- let mut value: Storage<DataComponent> = Storage::new();
- let any_ptr = &mut value as *mut _ as *mut Any;
- let dyn_ptr = &mut value as *mut _ as *mut DynamicCast;
- let w: Write<DataComponent> = unsafe { Write::new(any_ptr, dyn_ptr) };
- let r0 = w.downcast_dynamic::<Runable>();
- let r1 = w.downcast_dynamic::<Unrunable>();
- let r2 = w.downcast::<Storage<DataComponent>>();
- let r3 = w.downcast::<Storage<BadComponent>>();
- println!("Type: {:?}, Result: {:?}", type_name(&r0), option_result(&r0));
- println!("Type: {:?}, Result: {:?}", type_name(&r1), option_result(&r1));
- println!("Type: {:?}, Result: {:?}", type_name(&r2), option_result(&r2));
- println!("Type: {:?}, Result: {:?}", type_name(&r3), option_result(&r3));
- println!("{:?}", r0.unwrap().run());
- }
- fn type_name<T>(value: &T) -> &'static str {
- unsafe { std::intrinsics::type_name::<T>() }
- }
- fn option_result<T>(value: &Option<T>) -> &'static str {
- match value {
- Some(_) => "Some",
- None => "None"
- }
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement