Guest User

Untitled

a guest
Oct 22nd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. use std::marker::PhantomData;
  2. use std::ops::Deref;
  3.  
  4. // A reference-counted pointer.
  5. pub unsafe trait RcPtr {
  6. fn new<T>(t: T) -> Self;
  7. unsafe fn clone<T>(&self) -> Self;
  8. unsafe fn deref<T>(&self) -> &T;
  9. }
  10.  
  11. // Construct a type which wraps a reference-counted pointer (Rc or Arc), and
  12. // implements RcPtr.
  13. macro_rules! impl_rc_ptr {
  14. ($name:ident, $type_param:ident, $typ:ty, $new:path) => {
  15. struct $name {
  16. inner: *mut (),
  17. }
  18.  
  19. impl $name {
  20. unsafe fn inner<$type_param>(&self) -> &$typ {
  21. &*(self.inner as *const $typ)
  22. }
  23. }
  24.  
  25. unsafe impl RcPtr for $name {
  26. fn new<$type_param>(t: $type_param) -> Self {
  27. let inner = Box::new($new(t));
  28. // let inner = Box::new($typ::new(t));
  29. $name {
  30. inner: Box::into_raw(inner) as *mut (),
  31. }
  32. }
  33.  
  34. unsafe fn clone<$type_param>(&self) -> Self {
  35. let inner: &$typ = self.inner();
  36. let new_inner: $typ = inner.clone();
  37. let new_inner = Box::new(new_inner);
  38. $name {
  39. inner: Box::into_raw(new_inner) as *mut (),
  40. }
  41. }
  42.  
  43. unsafe fn deref<$type_param>(&self) -> &$type_param {
  44. let inner: &$typ = self.inner();
  45. inner.deref()
  46. }
  47. }
  48. };
  49. }
  50.  
  51. impl_rc_ptr!(SingleThreadedRc, T, std::rc::Rc<T>, std::rc::Rc::<T>::new);
  52. impl_rc_ptr!(
  53. MultiThreadedRc,
  54. T,
  55. std::sync::Arc<T>,
  56. std::sync::Arc::<T>::new
  57. );
  58.  
  59. // Instead of writing the native-HKT R<T>, write RcWrapper<R, T>.
  60. struct RcWrapper<R: RcPtr, T> {
  61. rc: R,
  62. _marker: PhantomData<T>,
  63. }
  64.  
  65. impl<R: RcPtr, T> RcWrapper<R, T> {
  66. fn new(t: T) -> Self {
  67. RcWrapper {
  68. rc: R::new::<T>(t),
  69. _marker: PhantomData,
  70. }
  71. }
  72. }
  73.  
  74. impl<R: RcPtr, T> Clone for RcWrapper<R, T> {
  75. fn clone(&self) -> Self {
  76. RcWrapper {
  77. rc: unsafe { self.rc.clone::<T>() },
  78. _marker: PhantomData,
  79. }
  80. }
  81. }
  82.  
  83. impl<R: RcPtr, T> Deref for RcWrapper<R, T> {
  84. type Target = T;
  85. fn deref(&self) -> &T {
  86. unsafe { self.rc.deref() }
  87. }
  88. }
  89.  
  90. mod tree {
  91. use super::*;
  92.  
  93. use std::fmt::{self, Debug, Formatter};
  94.  
  95. // A tree data structure with user-specified thread-safety.
  96. pub struct Tree<R: RcPtr, T> {
  97. root: Option<RcWrapper<R, TreeNode<R, T>>>,
  98. _marker: PhantomData<T>,
  99. }
  100.  
  101. struct TreeNode<R: RcPtr, T> {
  102. val: T,
  103. left: Option<RcWrapper<R, TreeNode<R, T>>>,
  104. right: Option<RcWrapper<R, TreeNode<R, T>>>,
  105. }
  106.  
  107. impl<R: RcPtr, T: Debug> Debug for Tree<R, T> {
  108. fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
  109. if let Some(root) = self.root.as_ref() {
  110. write!(f, "{:?}", root.deref())
  111. } else {
  112. write!(f, "{{}}")
  113. }
  114. }
  115. }
  116.  
  117. impl<R: RcPtr, T: Debug> Debug for TreeNode<R, T> {
  118. fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
  119. write!(f, "{{ val: {:?}", self.val)?;
  120. if let Some(left) = self.left.as_ref() {
  121. write!(f, ", left: {:?}", left.deref())?;
  122. }
  123. if let Some(right) = self.right.as_ref() {
  124. write!(f, ", right: {:?}", right.deref())?;
  125. }
  126. write!(f, " }}")
  127. }
  128. }
  129.  
  130. pub fn test_tree<R: RcPtr, T: Debug, F: FnMut() -> T>(mut new_t: F) {
  131. let left = TreeNode::<R, _> {
  132. val: new_t(),
  133. left: None,
  134. right: None,
  135. };
  136. let right = TreeNode::<R, _> {
  137. val: new_t(),
  138. left: None,
  139. right: None,
  140. };
  141. let tree = Tree {
  142. root: Some(RcWrapper::new(TreeNode {
  143. val: new_t(),
  144. left: Some(RcWrapper::new(left)),
  145. right: Some(RcWrapper::new(right)),
  146. })),
  147. _marker: PhantomData,
  148. };
  149. println!("{:?}", tree);
  150. }
  151. }
  152.  
  153. fn main() {
  154. use tree::test_tree;
  155.  
  156. let mut ctr = 0;
  157. test_tree::<SingleThreadedRc, usize, _>(|| {
  158. ctr += 1;
  159. ctr
  160. });
  161. test_tree::<SingleThreadedRc, String, _>(|| {
  162. ctr += 1;
  163. format!("{}", ctr)
  164. });
  165. test_tree::<MultiThreadedRc, usize, _>(|| {
  166. ctr += 1;
  167. ctr
  168. });
  169. test_tree::<MultiThreadedRc, String, _>(|| {
  170. ctr += 1;
  171. format!("{}", ctr)
  172. });
  173. }
Add Comment
Please, Sign In to add comment