Advertisement
Guest User

Untitled

a guest
Apr 26th, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.46 KB | None | 0 0
  1. #![feature(const_fn)]
  2. #![feature(untagged_unions)]
  3. #![feature(type_alias_enum_variants)]
  4. use std::sync::atomic::{Ordering, AtomicU8};
  5. use std::sync::Arc;
  6. use std::cell::UnsafeCell;
  7. use std::ops::Deref;
  8. use std::fmt::{Debug, Formatter, Error};
  9. use parking_lot_core::SpinWait; // 0.4.0
  10.  
  11. union Thunk<T, F: FnOnce()->T> {
  12. thunk: F,
  13. value: T,
  14. }
  15.  
  16. #[repr(u8)]
  17. enum ThunkState {
  18. Locked,
  19. Thunk,
  20. Complete,
  21. }
  22.  
  23. impl ThunkState {
  24. pub const LOCKED : u8 = Self::Locked as u8;
  25. pub const THUNK : u8 = Self::Thunk as u8;
  26. pub const COMPLETE : u8 = Self::Complete as u8;
  27. }
  28.  
  29. pub struct Lazy<T, F: FnOnce()->T> (UnsafeCell<Thunk<T, F>>, AtomicU8);
  30.  
  31. unsafe impl <T, F: FnOnce()->T> Sync for Lazy<T, F> where T: Sync, F: Send {}
  32.  
  33. impl <T, F: FnOnce()->T> Lazy<T, F> {
  34. pub const fn new(f: F) -> Self {
  35. Self(UnsafeCell::new(Thunk{thunk: f}), AtomicU8::new(ThunkState::LOCKED))
  36. }
  37.  
  38. pub const fn from_value(v: T) -> Self {
  39. Self(UnsafeCell::new(Thunk{value: v}), AtomicU8::new(ThunkState::COMPLETE))
  40. }
  41.  
  42. fn force(&self) {
  43. match self.1.compare_and_swap(ThunkState::THUNK, ThunkState::LOCKED, Ordering::AcqRel) {
  44. ThunkState::LOCKED => {
  45. let mut spin = SpinWait::new();
  46. while self.1.load(Ordering::Acquire) != ThunkState::COMPLETE{
  47. spin.spin();
  48. }
  49. }
  50. ThunkState::THUNK => unsafe {
  51. let f = self.0.get().read().thunk;
  52. let v = f();
  53. (*self.0.get()).value = v;
  54. self.1.store(ThunkState::COMPLETE, Ordering::Release);
  55. }
  56. ThunkState::COMPLETE => {},
  57. _ => unreachable!(),
  58. }
  59. }
  60. }
  61.  
  62. impl <T, F: FnOnce()->T> From<T> for Lazy<T, F> {
  63. fn from(val: T) -> Self {
  64. Self::from_value(val)
  65. }
  66. }
  67.  
  68. impl <T, F: FnOnce()->T> Deref for Lazy<T, F> {
  69. type Target = T;
  70. fn deref(&self) -> &T {
  71. self.force();
  72. unsafe { &(*self.0.get()).value }
  73. }
  74. }
  75.  
  76. impl <T, F: FnOnce()->T> Drop for Lazy<T, F> {
  77. fn drop(&mut self) {
  78. match self.1.load(Ordering::SeqCst) {
  79. ThunkState::COMPLETE => {
  80. let _ = unsafe { self.0.get().read().value };
  81. }
  82. ThunkState::THUNK => {
  83. let _ = unsafe { self.0.get().read().thunk };
  84. }
  85. ThunkState::COMPLETE => unreachable!(),
  86. _ => unreachable!(),
  87. }
  88. }
  89. }
  90.  
  91. #[derive(Clone)]
  92. pub enum ListInner<T> {
  93. Null,
  94. Cons(T, List<T>),
  95. }
  96.  
  97. #[derive(Clone)]
  98. pub struct List<T> (Arc<Lazy<ListInner<T>, Box<dyn FnOnce()->ListInner<T>>>>);
  99.  
  100. macro_rules! list {
  101. () => (List(Arc::new(Lazy::from_value(ListInner::Null))));
  102. (($head:expr) : $tail:expr) => (List(Arc::new(Lazy::from_value(ListInner::Cons($head, $tail)))));
  103. ($head:tt : $tail:expr) => (list![($head) : $tail]);
  104. ($head:expr $(,$tail:expr)*) => (list![($head) : list!($($tail)*)]);
  105. }
  106.  
  107. impl <T: Clone> List<T> {
  108. pub fn map<U>(&self, f: impl Fn(T)->U) -> List<U> {
  109. match **self {
  110. ListInner::Null => list![],
  111. ListInner::Cons(ref x, ref xs) => list!((f(x.clone())) : xs.map(f)),
  112. }
  113. }
  114.  
  115. pub fn append(&self, tail: Self) -> Self {
  116. match **self {
  117. ListInner::Null => tail,
  118. ListInner::Cons(ref x, ref xs) => list!((x.clone()) : xs.append(tail)),
  119. }
  120. }
  121.  
  122. pub fn flat_map<U: Clone>(&self, f: impl Fn(T)->List<U>) -> List<U> {
  123. List::flatten(&self.map(f))
  124. }
  125. }
  126.  
  127. impl <T> Deref for List<T> {
  128. type Target = ListInner<T>;
  129. fn deref(&self) -> &Self::Target {
  130. &**self.0
  131. }
  132. }
  133.  
  134. impl <T: Clone> List<List<T>> {
  135. pub fn flatten(&self) -> List<T> {
  136. match **self {
  137. ListInner::Null => list![],
  138. ListInner::Cons(ref x, ref xs) => x.append(xs.flatten()),
  139. }
  140. }
  141. }
  142.  
  143. impl <T: Debug> Debug for List<T> {
  144. fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
  145. let mut l = f.debug_list();
  146. let mut current = self;
  147. while let ListInner::Cons(ref x, ref xs) = **current {
  148. l.entry(x);
  149. current = xs;
  150. }
  151. l.finish()
  152. }
  153. }
  154.  
  155. fn prod(input: &List<List<i32>>) -> List<List<i32>> {
  156. match **input {
  157. ListInner::Null => list![list![]],
  158. ListInner::Cons(ref xs, ref xss) => {
  159. let p = prod(xss);
  160. xs.flat_map(|k| p.map(|t| list![(k.clone()) : t]))
  161. }
  162. }
  163. }
  164.  
  165. fn main() {
  166. println!("{:?}", prod(&list![list![1,2], list![3,4]]));
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement