Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::marker::PhantomData;
- trait UnRef {
- type UnRef;
- fn make_owned(self) -> Self::UnRef;
- }
- trait FamilyLt<'a> {
- type Out: Sized;
- }
- struct RefValue<T>(PhantomData<T>);
- impl<'a, T: 'a> FamilyLt<'a> for RefValue<T> {
- type Out = &'a T;
- }
- trait Extract<'a, I>: Sized {
- type Raw;
- type Out;
- fn extract(&'a self) -> Self::Out;
- }
- struct TupleIndex1;
- struct TupleIndex2;
- impl<'a, A: 'a, B> Extract<'a, TupleIndex1> for (A, B) {
- type Raw = A;
- type Out = &'a A;
- fn extract(&'a self) -> &'a A {
- &self.0
- }
- }
- impl<'a, A, B: 'a> Extract<'a, TupleIndex2> for (A, B) {
- type Raw = B;
- type Out = &'a B;
- fn extract(&'a self) -> &'a B {
- &self.1
- }
- }
- impl<'a, A, B, I1, I2> Extract<'a, (I1, I2)> for (A, B)
- where
- (A, B): Extract<'a, I1>,
- (A, B): Extract<'a, I2>,
- {
- type Raw = (<(A, B) as Extract<'a, I1>>::Raw, <(A, B) as Extract<'a, I2>>::Raw);
- type Out = (<(A, B) as Extract<'a, I1>>::Out, <(A, B) as Extract<'a, I2>>::Out);
- fn extract(&'a self) -> Self::Out {
- (
- <(A, B) as Extract<I1>>::extract(self),
- <(A, B) as Extract<I2>>::extract(self),
- )
- }
- }
- impl<'a, A> UnRef for &'a A
- where
- A: Clone,
- {
- type UnRef = A;
- fn make_owned(self) -> A {
- self.clone()
- }
- }
- impl<A, B> UnRef for (A, B)
- where
- A: UnRef,
- B: UnRef,
- {
- type UnRef = (A::UnRef, B::UnRef);
- fn make_owned(self) -> Self::UnRef {
- (self.0.make_owned(), self.1.make_owned())
- }
- }
- trait ExtractUnref<'a, I> {
- type Out: UnRef;
- fn extract(&'a self) -> Self::Out;
- }
- impl<'a, T, I> ExtractUnref<'a, I> for T
- where
- T: Extract<'a, I>,
- <T as Extract<'a, I>>::Out: UnRef,
- {
- type Out = <T as Extract<'a, I>>::Out;
- fn extract(&'a self) -> Self::Out {
- Extract::extract(self)
- }
- }
- fn generic<T, I>(t: T)
- where
- for<'a> T: ExtractUnref<'a, I>,
- {
- let borrowed = t.extract();
- let owned = borrowed.make_owned();
- }
- fn main() {
- let z = Some(String::from("foo"));
- let out = {
- let a = (z.clone(), z);
- generic::<_, (TupleIndex1, TupleIndex2)>(a);
- };
- }
Add Comment
Please, Sign In to add comment