Guest User

Untitled

a guest
Feb 17th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.11 KB | None | 0 0
  1. use std::marker::PhantomData;
  2.  
  3. trait UnRef {
  4. type UnRef;
  5.  
  6. fn make_owned(self) -> Self::UnRef;
  7. }
  8.  
  9. trait FamilyLt<'a> {
  10. type Out: Sized;
  11. }
  12.  
  13. struct RefValue<T>(PhantomData<T>);
  14.  
  15. impl<'a, T: 'a> FamilyLt<'a> for RefValue<T> {
  16. type Out = &'a T;
  17. }
  18.  
  19. trait Extract<'a, I>: Sized {
  20. type Raw;
  21. type Out;
  22.  
  23. fn extract(&'a self) -> Self::Out;
  24. }
  25. struct TupleIndex1;
  26. struct TupleIndex2;
  27.  
  28. impl<'a, A: 'a, B> Extract<'a, TupleIndex1> for (A, B) {
  29. type Raw = A;
  30. type Out = &'a A;
  31.  
  32. fn extract(&'a self) -> &'a A {
  33. &self.0
  34. }
  35. }
  36.  
  37. impl<'a, A, B: 'a> Extract<'a, TupleIndex2> for (A, B) {
  38. type Raw = B;
  39. type Out = &'a B;
  40.  
  41. fn extract(&'a self) -> &'a B {
  42. &self.1
  43. }
  44. }
  45.  
  46. impl<'a, A, B, I1, I2> Extract<'a, (I1, I2)> for (A, B)
  47. where
  48. (A, B): Extract<'a, I1>,
  49. (A, B): Extract<'a, I2>,
  50. {
  51. type Raw = (<(A, B) as Extract<'a, I1>>::Raw, <(A, B) as Extract<'a, I2>>::Raw);
  52. type Out = (<(A, B) as Extract<'a, I1>>::Out, <(A, B) as Extract<'a, I2>>::Out);
  53.  
  54. fn extract(&'a self) -> Self::Out {
  55. (
  56. <(A, B) as Extract<I1>>::extract(self),
  57. <(A, B) as Extract<I2>>::extract(self),
  58. )
  59. }
  60. }
  61.  
  62. impl<'a, A> UnRef for &'a A
  63. where
  64. A: Clone,
  65. {
  66. type UnRef = A;
  67.  
  68. fn make_owned(self) -> A {
  69. self.clone()
  70. }
  71. }
  72.  
  73. impl<A, B> UnRef for (A, B)
  74. where
  75. A: UnRef,
  76. B: UnRef,
  77. {
  78. type UnRef = (A::UnRef, B::UnRef);
  79.  
  80. fn make_owned(self) -> Self::UnRef {
  81. (self.0.make_owned(), self.1.make_owned())
  82. }
  83. }
  84.  
  85. trait ExtractUnref<'a, I> {
  86. type Out: UnRef;
  87.  
  88. fn extract(&'a self) -> Self::Out;
  89. }
  90.  
  91. impl<'a, T, I> ExtractUnref<'a, I> for T
  92. where
  93. T: Extract<'a, I>,
  94. <T as Extract<'a, I>>::Out: UnRef,
  95. {
  96. type Out = <T as Extract<'a, I>>::Out;
  97.  
  98. fn extract(&'a self) -> Self::Out {
  99. Extract::extract(self)
  100. }
  101. }
  102.  
  103. fn generic<T, I>(t: T)
  104. where
  105. for<'a> T: ExtractUnref<'a, I>,
  106. {
  107. let borrowed = t.extract();
  108. let owned = borrowed.make_owned();
  109. }
  110.  
  111. fn main() {
  112. let z = Some(String::from("foo"));
  113. let out = {
  114. let a = (z.clone(), z);
  115. generic::<_, (TupleIndex1, TupleIndex2)>(a);
  116. };
  117. }
Add Comment
Please, Sign In to add comment