From 536eceb1cfce9bd323a5cf45c3778445f9631cee Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Thu, 27 Jun 2024 14:15:39 -0700 Subject: [PATCH 1/8] variadics refs --- variadics/src/lib.rs | 109 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 24c643d6beca..fa0f8c0f2133 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -127,14 +127,14 @@ pub trait VariadicExt: Variadic { fn reverse(self) -> Self::Reverse; /// This as a variadic of references. - type AsRefVar<'a>: Copy + Variadic + type AsRefVar<'a>: RefVariadic where Self: 'a; /// Convert a reference to this variadic into a variadic of references. fn as_ref_var(&self) -> Self::AsRefVar<'_>; /// This as a variadic of exclusive (`mut`) references. - type AsMutVar<'a>: Variadic + type AsMutVar<'a>: MutVariadic where Self: 'a; /// Convert an exclusive (`mut`) reference to this variadic into a variadic of exclusive @@ -263,32 +263,111 @@ impl VariadicExt for () { } } -/// Convert from a variadic of references back into the original variadic. The inverse of -/// [`VariadicExt::as_ref_var`] or [`VariadicExt::as_mut_var`]. +/// A variadic where each item is a shared reference `&val`. /// /// This is a sealed trait. #[sealed] -pub trait UnrefVariadic: Variadic { - /// The un-referenced variadic. Each item will have one layer of references removed. - type Unref: VariadicExt; +pub trait RefVariadic: Variadic +where + Self: Copy, +{ + /// The un-referenced variadic. Each item will have one layer of shared references removed. + /// + /// The inverse of [`VariadicExt::AsRefVar`]. + type UnRef: VariadicExt; } #[sealed] -impl UnrefVariadic for (&Item, Rest) +impl RefVariadic for (&Item, Rest) where - Rest: UnrefVariadic, + Rest: RefVariadic, { - type Unref = (Item, Rest::Unref); + type UnRef = (Item, Rest::UnRef); +} +#[sealed] +impl RefVariadic for () { + type UnRef = (); +} + +/// A variadic where each item is a shared reference `&val`. +/// +/// This is a sealed trait. +#[sealed] +pub trait MutVariadic: Variadic { + /// The un-referenced variadic. Each item will have one layer of exclusive references removed. + /// + /// The inverse of [`VariadicExt::AsMutVar`]. + type UnMut: VariadicExt; + + /// Downgrade this to a shared reference [`RefVariadic`]. + type Downgrade: RefVariadic; + fn downgrade(self) -> Self::Downgrade; } #[sealed] -impl UnrefVariadic for (&mut Item, Rest) +impl<'a, Item, Rest> MutVariadic for (&'a mut Item, Rest) where - Rest: UnrefVariadic, + Rest: MutVariadic, { - type Unref = (Item, Rest::Unref); + type UnMut = (Item, Rest::UnMut); + + type Downgrade = (&'a Item, Rest::Downgrade); + fn downgrade(self) -> Self::Downgrade { + let var_args!(item, ...rest) = self; + var_expr!(&*item, ...rest) + } +} +#[sealed] +impl MutVariadic for () { + type UnMut = (); + + type Downgrade = (); + fn downgrade(self) -> Self::Downgrade {} +} + +#[sealed] +/// Clone an Unref +pub trait RefCloneVariadic: RefVariadic { + /// Clone the unref + fn clone_var(&self) -> Self::UnRef; } #[sealed] -impl UnrefVariadic for () { - type Unref = (); +impl RefCloneVariadic for (&Item, Rest) +where + Item: Clone, + Rest: RefCloneVariadic, +{ + fn clone_var(&self) -> Self::UnRef { + let var_args!(item, ...rest) = self; + var_expr!((*item).clone(), ...rest.clone_var()) + } +} +#[sealed] +impl RefCloneVariadic for () { + fn clone_var(&self) -> Self::UnRef {} +} + +/// `PartialEq` between a referenced variadic and a variadic of references, of the same types. +#[sealed] +pub trait AsRefVariadicPartialEq: VariadicExt { + /// `PartialEq` between a referenced variadic and a variadic of references, of the same types. + fn as_ref_var_eq(&self, other: Self::AsRefVar<'_>) -> bool; +} +#[sealed] +impl AsRefVariadicPartialEq for (Item, Rest) +where + Item: PartialEq, + Rest: AsRefVariadicPartialEq, +{ + fn as_ref_var_eq(&self, other: Self::AsRefVar<'_>) -> bool { + let var_args!(item_self, ...rest_self) = self; + let var_args!(item_other, ...rest_other) = other; + item_self == item_other && rest_self.as_ref_var_eq(rest_other) + } +} +#[sealed] +impl AsRefVariadicPartialEq for () { + fn as_ref_var_eq(&self, _other: Self::AsRefVar<'_>) -> bool { + true + } } /// A variadic where all elements are the same type, `T`. From 7bc3b85c9eb2951d90f4c937c01b5ee296bc486c Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Fri, 28 Jun 2024 12:37:05 -0700 Subject: [PATCH 2/8] wip --- variadics/src/lib.rs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index fa0f8c0f2133..7878721cd8cd 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -288,7 +288,7 @@ impl RefVariadic for () { type UnRef = (); } -/// A variadic where each item is a shared reference `&val`. +/// A variadic where each item is an exclusive reference `&mut val`. /// /// This is a sealed trait. #[sealed] @@ -298,8 +298,9 @@ pub trait MutVariadic: Variadic { /// The inverse of [`VariadicExt::AsMutVar`]. type UnMut: VariadicExt; - /// Downgrade this to a shared reference [`RefVariadic`]. + /// Type returned by [`Self::downgrade`]. type Downgrade: RefVariadic; + /// Downgrade this to a variadic of shared reference [`RefVariadic`]. fn downgrade(self) -> Self::Downgrade; } #[sealed] @@ -312,7 +313,7 @@ where type Downgrade = (&'a Item, Rest::Downgrade); fn downgrade(self) -> Self::Downgrade { let var_args!(item, ...rest) = self; - var_expr!(&*item, ...rest) + var_expr!(&*item, ...rest.downgrade()) } } #[sealed] @@ -324,16 +325,16 @@ impl MutVariadic for () { } #[sealed] -/// Clone an Unref -pub trait RefCloneVariadic: RefVariadic { - /// Clone the unref +/// Clone an [`RefVariadic`] into an [`RefVariadic::UnRef`] variadic of owned values. +pub trait CloneRefVariadic: RefVariadic { + /// Clone self per-value. fn clone_var(&self) -> Self::UnRef; } #[sealed] -impl RefCloneVariadic for (&Item, Rest) +impl CloneRefVariadic for (&Item, Rest) where Item: Clone, - Rest: RefCloneVariadic, + Rest: CloneRefVariadic, { fn clone_var(&self) -> Self::UnRef { let var_args!(item, ...rest) = self; @@ -341,31 +342,31 @@ where } } #[sealed] -impl RefCloneVariadic for () { +impl CloneRefVariadic for () { fn clone_var(&self) -> Self::UnRef {} } -/// `PartialEq` between a referenced variadic and a variadic of references, of the same types. +/// A variadic where all item implement `PartialEq`. #[sealed] -pub trait AsRefVariadicPartialEq: VariadicExt { +pub trait PartialEqVariadic: Variadic { /// `PartialEq` between a referenced variadic and a variadic of references, of the same types. - fn as_ref_var_eq(&self, other: Self::AsRefVar<'_>) -> bool; + fn eq(&self, other: &Self) -> bool; } #[sealed] -impl AsRefVariadicPartialEq for (Item, Rest) +impl PartialEqVariadic for (Item, Rest) where Item: PartialEq, - Rest: AsRefVariadicPartialEq, + Rest: PartialEqVariadic, { - fn as_ref_var_eq(&self, other: Self::AsRefVar<'_>) -> bool { + fn eq(&self, other: &Self) -> bool { let var_args!(item_self, ...rest_self) = self; let var_args!(item_other, ...rest_other) = other; - item_self == item_other && rest_self.as_ref_var_eq(rest_other) + item_self == item_other && rest_self.eq(rest_other) } } #[sealed] -impl AsRefVariadicPartialEq for () { - fn as_ref_var_eq(&self, _other: Self::AsRefVar<'_>) -> bool { +impl PartialEqVariadic for () { + fn eq(&self, _other: &Self) -> bool { true } } From b7e46721f6d5dda53098ad4f3d423a1ee8242a9d Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Fri, 28 Jun 2024 12:39:37 -0700 Subject: [PATCH 3/8] eq_ref --- variadics/src/lib.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 7878721cd8cd..70a6b3ca64ee 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -351,6 +351,11 @@ impl CloneRefVariadic for () { pub trait PartialEqVariadic: Variadic { /// `PartialEq` between a referenced variadic and a variadic of references, of the same types. fn eq(&self, other: &Self) -> bool; + + /// `PartialEq` for the `AsRefVar` version op `Self`. + fn eq_ref<'a>(this: Self::AsRefVar<'a>, other: Self::AsRefVar<'a>) -> bool + where + Self: VariadicExt; } #[sealed] impl PartialEqVariadic for (Item, Rest) @@ -363,12 +368,34 @@ where let var_args!(item_other, ...rest_other) = other; item_self == item_other && rest_self.eq(rest_other) } + + fn eq_ref<'a>( + this: ::AsRefVar<'a>, + other: ::AsRefVar<'a>, + ) -> bool + where + Self: VariadicExt, + { + let var_args!(item_self, ...rest_self) = this; + let var_args!(item_other, ...rest_other) = other; + item_self == item_other && rest_self.eq(rest_other) + } } #[sealed] impl PartialEqVariadic for () { fn eq(&self, _other: &Self) -> bool { true } + + fn eq_ref<'a>( + _this: ::AsRefVar<'a>, + _other: ::AsRefVar<'a>, + ) -> bool + where + Self: VariadicExt, + { + true + } } /// A variadic where all elements are the same type, `T`. From 58297fccb9064e8b990380448e077ca537779592 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Fri, 28 Jun 2024 12:45:11 -0700 Subject: [PATCH 4/8] fixup! eq_ref --- variadics/src/lib.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 70a6b3ca64ee..1c51bc7109a2 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -263,7 +263,7 @@ impl VariadicExt for () { } } -/// A variadic where each item is a shared reference `&val`. +/// A variadic where each item is a shared reference `&item`. /// /// This is a sealed trait. #[sealed] @@ -288,7 +288,7 @@ impl RefVariadic for () { type UnRef = (); } -/// A variadic where each item is an exclusive reference `&mut val`. +/// A variadic where each item is an exclusive reference `&mut item`. /// /// This is a sealed trait. #[sealed] @@ -348,14 +348,12 @@ impl CloneRefVariadic for () { /// A variadic where all item implement `PartialEq`. #[sealed] -pub trait PartialEqVariadic: Variadic { +pub trait PartialEqVariadic: VariadicExt { /// `PartialEq` between a referenced variadic and a variadic of references, of the same types. fn eq(&self, other: &Self) -> bool; /// `PartialEq` for the `AsRefVar` version op `Self`. - fn eq_ref<'a>(this: Self::AsRefVar<'a>, other: Self::AsRefVar<'a>) -> bool - where - Self: VariadicExt; + fn eq_ref<'a>(this: Self::AsRefVar<'a>, other: Self::AsRefVar<'a>) -> bool; } #[sealed] impl PartialEqVariadic for (Item, Rest) @@ -372,13 +370,10 @@ where fn eq_ref<'a>( this: ::AsRefVar<'a>, other: ::AsRefVar<'a>, - ) -> bool - where - Self: VariadicExt, - { + ) -> bool { let var_args!(item_self, ...rest_self) = this; let var_args!(item_other, ...rest_other) = other; - item_self == item_other && rest_self.eq(rest_other) + item_self == item_other && Rest::eq_ref(rest_self, rest_other) } } #[sealed] @@ -390,10 +385,7 @@ impl PartialEqVariadic for () { fn eq_ref<'a>( _this: ::AsRefVar<'a>, _other: ::AsRefVar<'a>, - ) -> bool - where - Self: VariadicExt, - { + ) -> bool { true } } From 6c50c8d03f4b3aac525483ac11fc5a26884acd32 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Mon, 1 Jul 2024 17:20:08 -0700 Subject: [PATCH 5/8] add doc tests --- variadics/src/lib.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 1c51bc7109a2..c3dc93b58512 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -131,6 +131,11 @@ pub trait VariadicExt: Variadic { where Self: 'a; /// Convert a reference to this variadic into a variadic of references. + /// ```rust + /// # use variadics::*; + /// let as_ref: var_type!(&u32, &String, &bool) = + /// var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var(); + /// ``` fn as_ref_var(&self) -> Self::AsRefVar<'_>; /// This as a variadic of exclusive (`mut`) references. @@ -139,6 +144,11 @@ pub trait VariadicExt: Variadic { Self: 'a; /// Convert an exclusive (`mut`) reference to this variadic into a variadic of exclusive /// (`mut`) references. + /// ```rust + /// # use variadics::*; + /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = + /// var_expr!(1_u32, "Hello".to_owned(), false).as_mut_var(); + /// ``` fn as_mut_var(&mut self) -> Self::AsMutVar<'_>; /// Iterator type returned by [`Self::iter_any_ref`]. @@ -265,6 +275,13 @@ impl VariadicExt for () { /// A variadic where each item is a shared reference `&item`. /// +/// This can be created using [`VariadicExt::as_ref_var`]: +/// ```rust +/// # use variadics::*; +/// let as_ref: var_type!(&u32, &String, &bool) = +/// var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var(); +/// ``` +/// /// This is a sealed trait. #[sealed] pub trait RefVariadic: Variadic @@ -274,6 +291,12 @@ where /// The un-referenced variadic. Each item will have one layer of shared references removed. /// /// The inverse of [`VariadicExt::AsRefVar`]. + /// + /// ```rust + /// # use variadics::*; + /// let un_ref: ::UnRef = + /// var_expr!(1_u32, "Hello".to_owned(), false); + /// ``` type UnRef: VariadicExt; } #[sealed] @@ -290,17 +313,39 @@ impl RefVariadic for () { /// A variadic where each item is an exclusive reference `&mut item`. /// +/// This can be created using [`VariadicExt::as_mut_var`]: +/// ```rust +/// # use variadics::*; +/// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = +/// var_expr!(1_u32, "Hello".to_owned(), false).as_mut_var(); +/// ``` +/// /// This is a sealed trait. #[sealed] pub trait MutVariadic: Variadic { /// The un-referenced variadic. Each item will have one layer of exclusive references removed. /// /// The inverse of [`VariadicExt::AsMutVar`]. + /// + /// ```rust + /// # use variadics::*; + /// let un_mut: ::UnMut = + /// var_expr!(1_u32, "Hello".to_owned(), false); + /// ``` type UnMut: VariadicExt; /// Type returned by [`Self::downgrade`]. type Downgrade: RefVariadic; /// Downgrade this to a variadic of shared reference [`RefVariadic`]. + /// + /// ```rust + /// # use variadics::*; + /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false); + /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var(); + /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.downgrade(); + /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version. + /// drop((as_ref_1, as_ref_2)); + /// ``` fn downgrade(self) -> Self::Downgrade; } #[sealed] From 60d03f703a1fec01c3c8174a5c365a4396dce368 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Tue, 2 Jul 2024 08:52:36 -0700 Subject: [PATCH 6/8] more fine-tuning --- variadics/src/lib.rs | 154 ++++++++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 44 deletions(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index c3dc93b58512..08709b2a4874 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -139,7 +139,7 @@ pub trait VariadicExt: Variadic { fn as_ref_var(&self) -> Self::AsRefVar<'_>; /// This as a variadic of exclusive (`mut`) references. - type AsMutVar<'a>: MutVariadic + type AsMutVar<'a>: MutVariadic where Self: 'a; /// Convert an exclusive (`mut`) reference to this variadic into a variadic of exclusive @@ -273,44 +273,64 @@ impl VariadicExt for () { } } -/// A variadic where each item is a shared reference `&item`. +/// A variadic of either shared references, exclusive references, or both. /// -/// This can be created using [`VariadicExt::as_ref_var`]: -/// ```rust -/// # use variadics::*; -/// let as_ref: var_type!(&u32, &String, &bool) = -/// var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var(); -/// ``` +/// Provides the [`Self::UnRef`] associated type which is the original variadic of owned values. /// /// This is a sealed trait. #[sealed] -pub trait RefVariadic: Variadic -where - Self: Copy, -{ +pub trait EitherRefVariadic { /// The un-referenced variadic. Each item will have one layer of shared references removed. /// - /// The inverse of [`VariadicExt::AsRefVar`]. + /// The inverse of [`VariadicExt::AsRefVar`] and [`VariadicExt::AsMutVar`]. /// /// ```rust /// # use variadics::*; /// let un_ref: ::UnRef = /// var_expr!(1_u32, "Hello".to_owned(), false); /// ``` - type UnRef: VariadicExt; + type UnRef: Variadic; } #[sealed] -impl RefVariadic for (&Item, Rest) +impl EitherRefVariadic for (&Item, Rest) where - Rest: RefVariadic, + Rest: EitherRefVariadic, { type UnRef = (Item, Rest::UnRef); } #[sealed] -impl RefVariadic for () { +impl EitherRefVariadic for (&mut Item, Rest) +where + Rest: EitherRefVariadic, +{ + type UnRef = (Item, Rest::UnRef); +} +#[sealed] +impl EitherRefVariadic for () { type UnRef = (); } +/// A variadic where each item is a shared reference `&item`. +/// +/// This can be created using [`VariadicExt::as_ref_var`]: +/// ```rust +/// # use variadics::*; +/// let as_ref: var_type!(&u32, &String, &bool) = +/// var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var(); +/// ``` +/// +/// This is a sealed trait. +#[sealed] +pub trait RefVariadic: EitherRefVariadic +where + Self: Copy, +{ +} +#[sealed] +impl RefVariadic for (&Item, Rest) where Rest: RefVariadic {} +#[sealed] +impl RefVariadic for () {} + /// A variadic where each item is an exclusive reference `&mut item`. /// /// This can be created using [`VariadicExt::as_mut_var`]: @@ -322,56 +342,91 @@ impl RefVariadic for () { /// /// This is a sealed trait. #[sealed] -pub trait MutVariadic: Variadic { - /// The un-referenced variadic. Each item will have one layer of exclusive references removed. - /// - /// The inverse of [`VariadicExt::AsMutVar`]. - /// - /// ```rust - /// # use variadics::*; - /// let un_mut: ::UnMut = - /// var_expr!(1_u32, "Hello".to_owned(), false); - /// ``` - type UnMut: VariadicExt; - - /// Type returned by [`Self::downgrade`]. - type Downgrade: RefVariadic; - /// Downgrade this to a variadic of shared reference [`RefVariadic`]. +pub trait MutVariadic: EitherRefVariadic { + /// Type returned by [`Self::mut_to_ref`]. + type MutToRef: RefVariadic; + /// Downgrade this to a variadic of shared references: [`RefVariadic`]. /// /// ```rust /// # use variadics::*; /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false); /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var(); - /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.downgrade(); + /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.mut_to_ref(); /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version. /// drop((as_ref_1, as_ref_2)); /// ``` - fn downgrade(self) -> Self::Downgrade; + fn mut_to_ref(self) -> Self::MutToRef; } #[sealed] impl<'a, Item, Rest> MutVariadic for (&'a mut Item, Rest) where Rest: MutVariadic, { - type UnMut = (Item, Rest::UnMut); - - type Downgrade = (&'a Item, Rest::Downgrade); - fn downgrade(self) -> Self::Downgrade { + type MutToRef = (&'a Item, Rest::MutToRef); + fn mut_to_ref(self) -> Self::MutToRef { let var_args!(item, ...rest) = self; - var_expr!(&*item, ...rest.downgrade()) + var_expr!(&*item, ...rest.mut_to_ref()) } } #[sealed] impl MutVariadic for () { - type UnMut = (); - - type Downgrade = (); - fn downgrade(self) -> Self::Downgrade {} + type MutToRef = (); + fn mut_to_ref(self) -> Self::MutToRef {} } +/// Copy an [`RefVariadic`] into an [`RefVariadic::UnRef`] variadic of owned values. +/// +/// ```rust +/// # use variadics::*; +/// let ref_var = var_expr!(&1, &"hello", &false); +/// let copy_var = ref_var.copy_var(); +/// assert_eq!(var_expr!(1, "hello", false), copy_var); +/// ``` +#[sealed] +pub trait CopyRefVariadic: EitherRefVariadic { + /// Copy self per-value. + fn copy_var(&self) -> Self::UnRef; +} #[sealed] +impl CopyRefVariadic for (&Item, Rest) +where + Item: Copy, + Rest: CopyRefVariadic, +{ + fn copy_var(&self) -> Self::UnRef { + let var_args!(&item, ...rest) = self; + var_expr!(item, ...rest.copy_var()) + } +} +#[sealed] +impl CopyRefVariadic for (&mut Item, Rest) +where + Item: Copy, + Rest: CopyRefVariadic, +{ + fn copy_var(&self) -> Self::UnRef { + let var_args!(&mut item, ...rest) = self; + var_expr!(item, ...rest.copy_var()) + } +} +#[sealed] +impl CopyRefVariadic for () { + fn copy_var(&self) -> Self::UnRef {} +} + /// Clone an [`RefVariadic`] into an [`RefVariadic::UnRef`] variadic of owned values. -pub trait CloneRefVariadic: RefVariadic { +/// +/// ```rust +/// # use variadics::*; +/// let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]); +/// let clone_var = ref_var.clone_var(); +/// assert_eq!( +/// var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]), +/// clone_var +/// ); +/// ``` +#[sealed] +pub trait CloneRefVariadic: EitherRefVariadic { /// Clone self per-value. fn clone_var(&self) -> Self::UnRef; } @@ -387,6 +442,17 @@ where } } #[sealed] +impl CloneRefVariadic for (&mut Item, Rest) +where + Item: Clone, + Rest: CloneRefVariadic, +{ + fn clone_var(&self) -> Self::UnRef { + let var_args!(item, ...rest) = self; + var_expr!((*item).clone(), ...rest.clone_var()) + } +} +#[sealed] impl CloneRefVariadic for () { fn clone_var(&self) -> Self::UnRef {} } From d58c07d02bf52becfee042da99bb41ad44b9fce2 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Tue, 2 Jul 2024 09:45:02 -0700 Subject: [PATCH 7/8] more changes --- variadics/src/lib.rs | 124 ++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 50 deletions(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 08709b2a4874..7f7da05ff926 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -127,7 +127,11 @@ pub trait VariadicExt: Variadic { fn reverse(self) -> Self::Reverse; /// This as a variadic of references. - type AsRefVar<'a>: RefVariadic + type AsRefVar<'a>: RefVariadic< + UnRefVar = Self, + RefVar = Self::AsRefVar<'a>, + MutVar = Self::AsMutVar<'a>, + > where Self: 'a; /// Convert a reference to this variadic into a variadic of references. @@ -139,7 +143,11 @@ pub trait VariadicExt: Variadic { fn as_ref_var(&self) -> Self::AsRefVar<'_>; /// This as a variadic of exclusive (`mut`) references. - type AsMutVar<'a>: MutVariadic + type AsMutVar<'a>: MutVariadic< + UnRefVar = Self, + RefVar = Self::AsRefVar<'a>, + MutVar = Self::AsMutVar<'a>, + > where Self: 'a; /// Convert an exclusive (`mut`) reference to this variadic into a variadic of exclusive @@ -275,7 +283,7 @@ impl VariadicExt for () { /// A variadic of either shared references, exclusive references, or both. /// -/// Provides the [`Self::UnRef`] associated type which is the original variadic of owned values. +/// Provides the [`Self::UnRefVar`] associated type which is the original variadic of owned values. /// /// This is a sealed trait. #[sealed] @@ -286,28 +294,70 @@ pub trait EitherRefVariadic { /// /// ```rust /// # use variadics::*; - /// let un_ref: ::UnRef = + /// let un_ref: ::UnRefVar = /// var_expr!(1_u32, "Hello".to_owned(), false); /// ``` - type UnRef: Variadic; + type UnRefVar: Variadic; + + /// This type with all exclusive `&mut` references replaced with shared `&` references. + /// + /// Returned by [`Self::mut_to_ref`]. + type RefVar: RefVariadic; + /// Convert all exclusive (`mut`) references into shared references: [`RefVariadic`]. + /// + /// ```rust + /// # use variadics::*; + /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false); + /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var(); + /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.mut_to_ref(); + /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version. + /// drop((as_ref_1, as_ref_2)); + /// ``` + fn mut_to_ref(self) -> Self::RefVar; + + /// This type with all shared `&` references replaced with exclusive references `&mut`. + /// + /// Conversion from `&` to `&mut` is generally invalid, so a `ref_to_mut()` method does not exist. + type MutVar: MutVariadic; } #[sealed] -impl EitherRefVariadic for (&Item, Rest) +impl<'a, Item, Rest> EitherRefVariadic for (&'a Item, Rest) where Rest: EitherRefVariadic, { - type UnRef = (Item, Rest::UnRef); + type UnRefVar = (Item, Rest::UnRefVar); + + type RefVar = (&'a Item, Rest::RefVar); + fn mut_to_ref(self) -> Self::RefVar { + let var_args!(item, ...rest) = self; + var_expr!(item, ...rest.mut_to_ref()) + } + + type MutVar = (&'a mut Item, Rest::MutVar); } #[sealed] -impl EitherRefVariadic for (&mut Item, Rest) +impl<'a, Item, Rest> EitherRefVariadic for (&'a mut Item, Rest) where Rest: EitherRefVariadic, { - type UnRef = (Item, Rest::UnRef); + type UnRefVar = (Item, Rest::UnRefVar); + + type RefVar = (&'a Item, Rest::RefVar); + fn mut_to_ref(self) -> Self::RefVar { + let var_args!(item, ...rest) = self; + var_expr!(&*item, ...rest.mut_to_ref()) + } + + type MutVar = (&'a mut Item, Rest::MutVar); } #[sealed] impl EitherRefVariadic for () { - type UnRef = (); + type UnRefVar = (); + + type RefVar = (); + fn mut_to_ref(self) -> Self::RefVar {} + + type MutVar = (); } /// A variadic where each item is a shared reference `&item`. @@ -321,7 +371,7 @@ impl EitherRefVariadic for () { /// /// This is a sealed trait. #[sealed] -pub trait RefVariadic: EitherRefVariadic +pub trait RefVariadic: EitherRefVariadic where Self: Copy, { @@ -342,39 +392,13 @@ impl RefVariadic for () {} /// /// This is a sealed trait. #[sealed] -pub trait MutVariadic: EitherRefVariadic { - /// Type returned by [`Self::mut_to_ref`]. - type MutToRef: RefVariadic; - /// Downgrade this to a variadic of shared references: [`RefVariadic`]. - /// - /// ```rust - /// # use variadics::*; - /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false); - /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var(); - /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.mut_to_ref(); - /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version. - /// drop((as_ref_1, as_ref_2)); - /// ``` - fn mut_to_ref(self) -> Self::MutToRef; -} +pub trait MutVariadic: EitherRefVariadic {} #[sealed] -impl<'a, Item, Rest> MutVariadic for (&'a mut Item, Rest) -where - Rest: MutVariadic, -{ - type MutToRef = (&'a Item, Rest::MutToRef); - fn mut_to_ref(self) -> Self::MutToRef { - let var_args!(item, ...rest) = self; - var_expr!(&*item, ...rest.mut_to_ref()) - } -} +impl MutVariadic for (&mut Item, Rest) where Rest: MutVariadic {} #[sealed] -impl MutVariadic for () { - type MutToRef = (); - fn mut_to_ref(self) -> Self::MutToRef {} -} +impl MutVariadic for () {} -/// Copy an [`RefVariadic`] into an [`RefVariadic::UnRef`] variadic of owned values. +/// Copy an [`RefVariadic`] into an [`RefVariadic::UnRefVar`] variadic of owned values. /// /// ```rust /// # use variadics::*; @@ -385,7 +409,7 @@ impl MutVariadic for () { #[sealed] pub trait CopyRefVariadic: EitherRefVariadic { /// Copy self per-value. - fn copy_var(&self) -> Self::UnRef; + fn copy_var(&self) -> Self::UnRefVar; } #[sealed] impl CopyRefVariadic for (&Item, Rest) @@ -393,7 +417,7 @@ where Item: Copy, Rest: CopyRefVariadic, { - fn copy_var(&self) -> Self::UnRef { + fn copy_var(&self) -> Self::UnRefVar { let var_args!(&item, ...rest) = self; var_expr!(item, ...rest.copy_var()) } @@ -404,17 +428,17 @@ where Item: Copy, Rest: CopyRefVariadic, { - fn copy_var(&self) -> Self::UnRef { + fn copy_var(&self) -> Self::UnRefVar { let var_args!(&mut item, ...rest) = self; var_expr!(item, ...rest.copy_var()) } } #[sealed] impl CopyRefVariadic for () { - fn copy_var(&self) -> Self::UnRef {} + fn copy_var(&self) -> Self::UnRefVar {} } -/// Clone an [`RefVariadic`] into an [`RefVariadic::UnRef`] variadic of owned values. +/// Clone a variadic of references [`EitherRefVariadic`] into a variadic of owned values [`EitherRefVariadic::UnRefVar`]. /// /// ```rust /// # use variadics::*; @@ -428,7 +452,7 @@ impl CopyRefVariadic for () { #[sealed] pub trait CloneRefVariadic: EitherRefVariadic { /// Clone self per-value. - fn clone_var(&self) -> Self::UnRef; + fn clone_var(&self) -> Self::UnRefVar; } #[sealed] impl CloneRefVariadic for (&Item, Rest) @@ -436,7 +460,7 @@ where Item: Clone, Rest: CloneRefVariadic, { - fn clone_var(&self) -> Self::UnRef { + fn clone_var(&self) -> Self::UnRefVar { let var_args!(item, ...rest) = self; var_expr!((*item).clone(), ...rest.clone_var()) } @@ -447,14 +471,14 @@ where Item: Clone, Rest: CloneRefVariadic, { - fn clone_var(&self) -> Self::UnRef { + fn clone_var(&self) -> Self::UnRefVar { let var_args!(item, ...rest) = self; var_expr!((*item).clone(), ...rest.clone_var()) } } #[sealed] impl CloneRefVariadic for () { - fn clone_var(&self) -> Self::UnRef {} + fn clone_var(&self) -> Self::UnRefVar {} } /// A variadic where all item implement `PartialEq`. From 04be03573ac0153f1f9ab3c58ee4eeab01d1a956 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Tue, 2 Jul 2024 10:22:22 -0700 Subject: [PATCH 8/8] fixup! more changes --- variadics/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index 7f7da05ff926..dd6f2df74f1c 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -398,7 +398,7 @@ impl MutVariadic for (&mut Item, Rest) where Rest: MutVariadic {} #[sealed] impl MutVariadic for () {} -/// Copy an [`RefVariadic`] into an [`RefVariadic::UnRefVar`] variadic of owned values. +/// Copy a variadic of references [`EitherRefVariadic`] into a variadic of owned values [`EitherRefVariadic::UnRefVar`]. /// /// ```rust /// # use variadics::*;