Guest User

Untitled

a guest
Feb 18th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.92 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::{Any, TypeId};
  8. use std::cell::Cell;
  9. use std::marker::PhantomData;
  10. use std::raw::TraitObject;
  11.  
  12. // Mocks
  13.  
  14. pub trait DynamicCast {
  15. fn __cast<'a>(&'a self, target_type: std::any::TypeId) -> Option<TraitObject>;
  16. }
  17.  
  18. impl DynamicCast {
  19. pub fn cast<'a, T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
  20. if let Some(trait_obj) = self.__cast(TypeId::of::<T>()) {
  21. let value = unsafe {
  22. *(&trait_obj as *const TraitObject as *const &'a T)
  23. };
  24.  
  25. Some(value)
  26. }
  27. else {
  28. None
  29. }
  30. }
  31.  
  32. pub fn cast_mut<'a, T: ?Sized + 'static>(&'a mut self) -> Option<&'a mut T> {
  33. if let Some(mut trait_obj) = self.__cast(TypeId::of::<T>()) {
  34. let value = {
  35. &mut trait_obj as *mut TraitObject as *mut &'a mut T
  36. };
  37.  
  38. Some(unsafe { *value })
  39. }
  40. else {
  41. None
  42. }
  43. }
  44. }
  45.  
  46. trait Component: Sized + 'static { }
  47.  
  48. trait Runable {
  49. fn run(&self) -> &'static str {
  50. "Default trait method"
  51. }
  52. }
  53.  
  54. trait Unrunable {}
  55.  
  56. struct DataComponent {
  57. data: f32
  58. }
  59.  
  60. struct BadComponent {}
  61.  
  62. impl Component for DataComponent {}
  63. impl Component for BadComponent {}
  64.  
  65. struct Storage<T: Component> {
  66. _marker: PhantomData<T>
  67. }
  68.  
  69. impl<T: Component> Storage<T> {
  70. fn new() -> Self {
  71. Self {
  72. _marker: PhantomData
  73. }
  74. }
  75. }
  76.  
  77. impl<T: Component> Runable for Storage<T> {
  78. fn run(&self) -> &'static str {
  79. "Storage method"
  80. }
  81. }
  82.  
  83. impl<T: Component> DynamicCast for Storage<T> {
  84. fn __cast<'a>(&'a self, target: std::any::TypeId) -> Option<std::raw::TraitObject> {
  85. if target == std::any::TypeId::of::<Runable>() {
  86. let trait_obj = unsafe {
  87. std::mem::transmute(self as &'a Runable)
  88. };
  89.  
  90. return Some(trait_obj);
  91. }
  92.  
  93. return None;
  94. }
  95. }
  96.  
  97. trait Storable: Any + DynamicCast {}
  98.  
  99. impl<T> Storable for T
  100. where T: Any + DynamicCast
  101. { }
  102.  
  103. // Impl
  104. struct RefCount {
  105. count: Cell<isize>
  106. }
  107.  
  108. impl RefCount {
  109. pub fn new() -> Self {
  110. RefCount {
  111. count: Cell::new(0)
  112. }
  113. }
  114.  
  115. pub fn increment_read(&mut self) {
  116. self.count.set(
  117. self.count.get() + 1
  118. );
  119. }
  120.  
  121. pub fn decrement_read(&mut self) {
  122. self.count.set(
  123. self.count.get() - 1
  124. );
  125. }
  126.  
  127. pub fn increment_write(&mut self) {
  128. self.count.set(
  129. self.count.get() - 1
  130. );
  131. }
  132.  
  133. pub fn decrement_write(&mut self) {
  134. self.count.set(
  135. self.count.get() + 1
  136. );
  137. }
  138.  
  139. #[inline]
  140. pub fn is_write(&self) -> bool {
  141. self.count.get() < 0
  142. }
  143.  
  144. #[inline]
  145. pub fn is_read(&self) -> bool {
  146. self.count.get() > 0
  147. }
  148. }
  149.  
  150. struct Write<T: Component> {
  151. any_ptr: *mut Any,
  152. dyn_ptr: *mut DynamicCast,
  153. ref_count: RefCount,
  154. _marker: PhantomData<T>
  155. }
  156.  
  157. impl<T: Component> Write<T> {
  158. unsafe fn new(any_ptr: *mut Any, dyn_ptr: *mut DynamicCast) -> Self {
  159. Self {
  160. any_ptr: any_ptr,
  161. dyn_ptr: dyn_ptr,
  162. ref_count: RefCount::new(),
  163. _marker: PhantomData
  164. }
  165. }
  166.  
  167. fn downcast<U: 'static>(&self) -> Option<&U> {
  168. unsafe {
  169. (&*self.any_ptr).downcast_ref::<U>()
  170. }
  171. }
  172.  
  173. fn downcast_mut<U: 'static>(&mut self) -> Option<&mut U> {
  174. unsafe {
  175. (&mut *self.any_ptr).downcast_mut::<U>()
  176. }
  177. }
  178.  
  179. fn downcast_dynamic<U: ?Sized + 'static>(&self) -> Option<&U> {
  180. unsafe {
  181. (&*self.dyn_ptr).cast::<U>()
  182. }
  183. }
  184.  
  185. fn downcast_dynamic_mut<U: ?Sized + 'static>(&mut self) -> Option<&mut U> {
  186. unsafe {
  187. (&mut *self.dyn_ptr).cast_mut::<U>()
  188. }
  189. }
  190. }
  191.  
  192. fn main() {
  193. let mut value: Storage<DataComponent> = Storage::new();
  194. let any_ptr = &mut value as *mut _ as *mut Any;
  195. let dyn_ptr = &mut value as *mut _ as *mut DynamicCast;
  196.  
  197. let w: Write<DataComponent> = unsafe { Write::new(any_ptr, dyn_ptr) };
  198.  
  199. let r0 = w.downcast_dynamic::<Runable>();
  200. let r1 = w.downcast_dynamic::<Unrunable>();
  201. let r2 = w.downcast::<Storage<DataComponent>>();
  202. let r3 = w.downcast::<Storage<BadComponent>>();
  203.  
  204. println!("Type: {:?}, Result: {:?}", type_name(&r0), option_result(&r0));
  205. println!("Type: {:?}, Result: {:?}", type_name(&r1), option_result(&r1));
  206. println!("Type: {:?}, Result: {:?}", type_name(&r2), option_result(&r2));
  207. println!("Type: {:?}, Result: {:?}", type_name(&r3), option_result(&r3));
  208.  
  209. println!("{:?}", r0.unwrap().run());
  210. }
  211.  
  212. fn type_name<T>(value: &T) -> &'static str {
  213. unsafe { std::intrinsics::type_name::<T>() }
  214. }
  215.  
  216. fn option_result<T>(value: &Option<T>) -> &'static str {
  217. match value {
  218. Some(_) => "Some",
  219. None => "None"
  220. }
  221. }
Add Comment
Please, Sign In to add comment