Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.59 KB | None | 0 0
  1. #![feature(core_intrinsics)]
  2. #![feature(raw)]
  3.  
  4. #![allow(unused_variables)]
  5. #![allow(dead_code)]
  6.  
  7. use std::any::TypeId;
  8. use std::raw::TraitObject;
  9.  
  10. pub trait AsDyn {
  11. fn __as_dyn<'a>(&'a self, id: TypeId) -> Option<TraitObject>;
  12.  
  13. fn __as_dyn_mut<'a>(&'a mut self, target_type: TypeId) -> Option<TraitObject>;
  14. }
  15.  
  16. impl AsDyn {
  17. pub fn as_dyn<'a, T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
  18. if let Some(trait_obj) = self.__as_dyn(TypeId::of::<T>()) {
  19. let value = unsafe {
  20. *(&trait_obj as *const TraitObject as *const &'a T)
  21. };
  22.  
  23. Some(value)
  24. }
  25. else {
  26. None
  27. }
  28. }
  29.  
  30. pub fn as_dyn_mut<'a, T: ?Sized + 'static>(&'a mut self) -> Option<&'a mut T> {
  31. if let Some(mut trait_obj) = self.__as_dyn_mut(TypeId::of::<T>()) {
  32. let value = {
  33. &mut trait_obj as *mut TraitObject as *mut &'a mut T
  34. };
  35.  
  36. Some(unsafe { *value })
  37. }
  38. else {
  39. None
  40. }
  41. }
  42. }
  43.  
  44. macro_rules! as_dyn {
  45. // Trait implementation
  46. (
  47. [$( $target_ty:ty ),*]
  48. impl<$($args:ident),* $(,)*> AsDyn for $type:ty
  49. where $( $preds:tt )+
  50. )
  51. => {
  52. impl<$( $args )*> AsDyn for $type
  53. where $($preds)*
  54. {
  55. fn __as_dyn<'a>(&'a self, id: std::any::TypeId) -> Option<std::raw::TraitObject> {
  56. $(
  57. as_dyn!(self, id, $target_ty);
  58. )*
  59.  
  60. None
  61. }
  62.  
  63. fn __as_dyn_mut<'a>(&'a mut self, id: std::any::TypeId) -> Option<std::raw::TraitObject> {
  64. $(
  65. as_dyn!(self, id, mut $target_ty);
  66. )*
  67.  
  68. None
  69. }
  70. }
  71. };
  72.  
  73. // Mutable implementation
  74. ($self:ident, $id:ident, mut $ty:ty) => {
  75. if $id == std::any::TypeId::of::<$ty>() {
  76. let trait_obj = unsafe {
  77. std::mem::transmute($self as &'a mut $ty)
  78. };
  79.  
  80. return Some(trait_obj);
  81. }
  82. };
  83.  
  84. // Immutable implementation
  85. ($self:ident, $id:ident, $ty:ty) => {
  86. if $id == std::any::TypeId::of::<$ty>() {
  87. let trait_obj = unsafe {
  88. std::mem::transmute($self as &'a $ty)
  89. };
  90.  
  91. return Some(trait_obj);
  92. }
  93. };
  94. }
  95.  
  96. trait A {
  97. fn run(&self) -> &'static str {
  98. "A"
  99. }
  100. }
  101. trait B {
  102. fn run(&self) -> &'static str {
  103. "B"
  104. }
  105. }
  106. trait C<T> {
  107. fn run(&self, _v: T) -> &'static str {
  108. "C<T>"
  109. }
  110. }
  111. trait D {
  112. fn run(&self) -> &'static str {
  113. "D"
  114. }
  115. }
  116. trait E<T> {
  117. fn run(&self, _v: T) -> &'static str {
  118. "E<T>"
  119. }
  120. }
  121.  
  122. struct Implementor<T> {
  123. v: T
  124. }
  125.  
  126. impl<T> A for Implementor<T> {}
  127. impl<T> B for Implementor<T> {}
  128. impl<T> C<T> for Implementor<T> {}
  129. impl<T> E<usize> for Implementor<T> {}
  130.  
  131. as_dyn!(
  132. [ A, B, C<T>, E<usize> ]
  133. impl<T> AsDyn for Implementor<T>
  134. where T: 'static
  135. );
  136.  
  137. fn main() {
  138. let mut i = Implementor { v: 0.0_f32 };
  139. let x: &mut dyn AsDyn = &mut i;
  140.  
  141. let a = x.as_dyn::<A>();
  142. let b = x.as_dyn::<B>();
  143. let c = x.as_dyn::<C<f32>>();
  144. let d = x.as_dyn::<D>();
  145. let e = x.as_dyn::<E<usize>>();
  146.  
  147. println!(
  148. "A: {}, B: {}, C: {}, D: {}, E: {}",
  149. opt_as_str(&a),
  150. opt_as_str(&b),
  151. opt_as_str(&c),
  152. opt_as_str(&d),
  153. opt_as_str(&e)
  154. );
  155. }
  156.  
  157. fn opt_as_str<T>(opt: &Option<T>) -> &'static str {
  158. match opt {
  159. Some(_) => "Some",
  160. None => "None"
  161. }
  162. }
  163.  
  164. /*
  165. fn main() {
  166. let mut value: Storage<DataComponent> = Storage::new();
  167. let any_ptr = &mut value as *mut _ as *mut Any;
  168. let dyn_ptr = &mut value as *mut _ as *mut DynamicCast;
  169.  
  170. let w: Write<DataComponent> = unsafe { Write::new(any_ptr, dyn_ptr) };
  171.  
  172. let r0 = w.downcast_dynamic::<Runable>();
  173. let r1 = w.downcast_dynamic::<Unrunable>();
  174. let r2 = w.downcast::<Storage<DataComponent>>();
  175. let r3 = w.downcast::<Storage<BadComponent>>();
  176.  
  177. println!("Type: {:?}, Result: {:?}", type_name(&r0), option_result(&r0));
  178. println!("Type: {:?}, Result: {:?}", type_name(&r1), option_result(&r1));
  179. println!("Type: {:?}, Result: {:?}", type_name(&r2), option_result(&r2));
  180. println!("Type: {:?}, Result: {:?}", type_name(&r3), option_result(&r3));
  181.  
  182. println!("{:?}", r0.unwrap().run());
  183. }
  184.  
  185. fn type_name<T>(value: &T) -> &'static str {
  186. unsafe { std::intrinsics::type_name::<T>() }
  187. }
  188.  
  189. fn option_result<T>(value: &Option<T>) -> &'static str {
  190. match value {
  191. Some(_) => "Some",
  192. None => "None"
  193. }
  194. }
  195. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement