From 081f7427015ec6c8a27dd55824dd6f231276a393 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 11 Jan 2023 13:09:02 +0100 Subject: [PATCH 1/6] Make name of associated type more specific --- crates/fj-kernel/src/builder/cycle.rs | 4 ++-- crates/fj-kernel/src/builder/mod.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/fj-kernel/src/builder/cycle.rs b/crates/fj-kernel/src/builder/cycle.rs index 107016e86..08ed10ab0 100644 --- a/crates/fj-kernel/src/builder/cycle.rs +++ b/crates/fj-kernel/src/builder/cycle.rs @@ -38,7 +38,7 @@ pub trait CycleBuilder { fn update_as_polygon_from_points( &mut self, points: O, - ) -> O::ReturnValue> + ) -> O::SameSize> where O: ObjectArgument

, P: Into>; @@ -130,7 +130,7 @@ impl CycleBuilder for PartialCycle { fn update_as_polygon_from_points( &mut self, points: O, - ) -> O::ReturnValue> + ) -> O::SameSize> where O: ObjectArgument

, P: Into>, diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 6eeae17cf..2d557526f 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -40,18 +40,18 @@ pub trait ObjectArgument: IntoIterator { /// The return value has the same length as the implementing type, but it is /// not necessarily of the same type. For this reason, this associated type /// is generic. - type ReturnValue; + type SameSize; /// Create a return value by mapping the implementing type - fn map(self, f: F) -> Self::ReturnValue + fn map(self, f: F) -> Self::SameSize where F: FnMut(T) -> R; } impl ObjectArgument for Vec { - type ReturnValue = Vec; + type SameSize = Vec; - fn map(self, mut f: F) -> Self::ReturnValue + fn map(self, mut f: F) -> Self::SameSize where F: FnMut(T) -> R, { @@ -66,9 +66,9 @@ impl ObjectArgument for Vec { } impl ObjectArgument for [T; N] { - type ReturnValue = [R; N]; + type SameSize = [R; N]; - fn map(self, f: F) -> Self::ReturnValue + fn map(self, f: F) -> Self::SameSize where F: FnMut(T) -> R, { From 06ec4805ee92851919caa95f7ff48583a5fbb719 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 11 Jan 2023 13:36:07 +0100 Subject: [PATCH 2/6] Split `ObjectArgument` implementation for arrays This is unfortunately required for the next feature I'm adding to the trait, at least for now. --- crates/fj-kernel/src/builder/mod.rs | 33 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 2d557526f..ec7a8d775 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -65,13 +65,30 @@ impl ObjectArgument for Vec { } } -impl ObjectArgument for [T; N] { - type SameSize = [R; N]; +macro_rules! impl_object_argument_for_arrays { + ($($len:expr;)*) => { + $( + impl ObjectArgument for [T; $len] { + type SameSize = [R; $len]; - fn map(self, f: F) -> Self::SameSize - where - F: FnMut(T) -> R, - { - self.map(f) - } + fn map(self, f: F) -> Self::SameSize + where + F: FnMut(T) -> R, + { + self.map(f) + } + } + )* + }; } + +impl_object_argument_for_arrays!( + 0; + 1; + 2; + 3; + 4; + 5; + 6; + 7; +); From 932cedf880ab5b57ea237ef57148443c72dac9d3 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 11 Jan 2023 13:38:40 +0100 Subject: [PATCH 3/6] Add `ObjectArgument::SizePlusOne` --- crates/fj-kernel/src/builder/mod.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index ec7a8d775..b4f7aeae0 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -42,6 +42,9 @@ pub trait ObjectArgument: IntoIterator { /// is generic. type SameSize; + /// A return value that has one more element thatn the argument + type SizePlusOne; + /// Create a return value by mapping the implementing type fn map(self, f: F) -> Self::SameSize where @@ -50,6 +53,7 @@ pub trait ObjectArgument: IntoIterator { impl ObjectArgument for Vec { type SameSize = Vec; + type SizePlusOne = Vec; fn map(self, mut f: F) -> Self::SameSize where @@ -66,10 +70,11 @@ impl ObjectArgument for Vec { } macro_rules! impl_object_argument_for_arrays { - ($($len:expr;)*) => { + ($($len:expr, $len_plus_one:expr;)*) => { $( impl ObjectArgument for [T; $len] { type SameSize = [R; $len]; + type SizePlusOne = [R; $len_plus_one]; fn map(self, f: F) -> Self::SameSize where @@ -83,12 +88,12 @@ macro_rules! impl_object_argument_for_arrays { } impl_object_argument_for_arrays!( - 0; - 1; - 2; - 3; - 4; - 5; - 6; - 7; + 0, 1; + 1, 2; + 2, 3; + 3, 4; + 4, 5; + 5, 6; + 6, 7; + 7, 8; ); From 8e8c26d9b11d1ad3b892f3492ccd8511022f830c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 11 Jan 2023 15:25:06 +0100 Subject: [PATCH 4/6] Add `ObjectArgument::map_plus_one` --- crates/fj-kernel/src/builder/mod.rs | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index b4f7aeae0..ba89311c3 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -11,6 +11,8 @@ mod solid; mod surface; mod vertex; +use std::array; + pub use self::{ curve::CurveBuilder, cycle::CycleBuilder, @@ -49,6 +51,11 @@ pub trait ObjectArgument: IntoIterator { fn map(self, f: F) -> Self::SameSize where F: FnMut(T) -> R; + + /// Create a return value with one more element + fn map_plus_one(self, item: R, f: F) -> Self::SizePlusOne + where + F: FnMut(T) -> R; } impl ObjectArgument for Vec { @@ -67,6 +74,15 @@ impl ObjectArgument for Vec { ret } + + fn map_plus_one(self, item: R, f: F) -> Self::SizePlusOne + where + F: FnMut(T) -> R, + { + let mut ret = self.map(f); + ret.push(item); + ret + } } macro_rules! impl_object_argument_for_arrays { @@ -82,6 +98,21 @@ macro_rules! impl_object_argument_for_arrays { { self.map(f) } + + fn map_plus_one(self, item: R, mut f: F) + -> Self::SizePlusOne + where + F: FnMut(T) -> R, + { + let mut tmp = array::from_fn(|_| None); + for (i, item) in self.into_iter().enumerate() { + tmp[i] = Some(f(item)); + } + + tmp[tmp.len() - 1] = Some(item); + + tmp.map(Option::unwrap) + } } )* }; From e04f42bc911e9566441306deec022a86b1116607 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 11 Jan 2023 15:29:53 +0100 Subject: [PATCH 5/6] Add comment --- crates/fj-kernel/src/builder/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index ba89311c3..234684ead 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -85,6 +85,10 @@ impl ObjectArgument for Vec { } } +// This macro implements `ObjectArgument` for a number of array types. This +// should just be a single implementation, but while const generic expressions +// are still unstable, this is unfortunately not possible: +// macro_rules! impl_object_argument_for_arrays { ($($len:expr, $len_plus_one:expr;)*) => { $( From 6b201ffa39c196a294eff5adce1ceed0a62d59fe Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 13 Jan 2023 13:19:02 +0100 Subject: [PATCH 6/6] Add `ObjectArgument::num_objects` --- crates/fj-kernel/src/builder/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/fj-kernel/src/builder/mod.rs b/crates/fj-kernel/src/builder/mod.rs index 234684ead..9fd19b034 100644 --- a/crates/fj-kernel/src/builder/mod.rs +++ b/crates/fj-kernel/src/builder/mod.rs @@ -47,6 +47,9 @@ pub trait ObjectArgument: IntoIterator { /// A return value that has one more element thatn the argument type SizePlusOne; + /// Return the number of objects + fn num_objects(&self) -> usize; + /// Create a return value by mapping the implementing type fn map(self, f: F) -> Self::SameSize where @@ -62,6 +65,10 @@ impl ObjectArgument for Vec { type SameSize = Vec; type SizePlusOne = Vec; + fn num_objects(&self) -> usize { + self.len() + } + fn map(self, mut f: F) -> Self::SameSize where F: FnMut(T) -> R, @@ -96,6 +103,10 @@ macro_rules! impl_object_argument_for_arrays { type SameSize = [R; $len]; type SizePlusOne = [R; $len_plus_one]; + fn num_objects(&self) -> usize { + self.len() + } + fn map(self, f: F) -> Self::SameSize where F: FnMut(T) -> R,