From 6933dd86281d66b3852258181858eba2b6c5c6ee Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Thu, 9 Mar 2023 22:54:29 +1000 Subject: [PATCH 1/9] Add reserve method for owned arrays --- src/impl_owned_array.rs | 48 +++++++++++++++++++++++++++++++------ tests/reserve.rs | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 tests/reserve.rs diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index c7bf603b5..3b393a6d7 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -660,14 +660,10 @@ where D: Dimension self.strides.clone() }; - unsafe { - // grow backing storage and update head ptr - let offset_from_alloc_to_logical = self.offset_from_alloc_to_logical_ptr().unwrap_or(0); - self.ptr = self - .data - .reserve(len_to_append) - .add(offset_from_alloc_to_logical); + // grow backing storage and update head ptr + self.reserve(axis, array_dim[axis.index()]); + unsafe { // clone elements from view to the array now // // To be robust for panics and drop the right elements, we want @@ -751,6 +747,44 @@ where D: Dimension Ok(()) } + + /// Reserve capacity to grow array along `axis` by at least `additional` elements. + /// + /// Existing elements of `array` are untouched and the backing storage is grown by + /// calling the underlying `reserve` method of the `OwnedRepr`. + /// + /// This is useful when pushing or appending repeatedly to an array to avoid multiple + /// allocations. + /// + /// ```rust + /// use ndarray::{Array3, Axis}; + /// let mut a = Array3::::zeros((0,2,4)); + /// a.reserve(Axis(0), 1000); + /// assert!(a.into_raw_vec().capacity() >= 2*4*1000); + pub fn reserve(&mut self, axis: Axis, additional: usize) + where D: RemoveAxis + { + if additional == 0 { + return; + } + let self_dim = self.raw_dim(); + let remaining_shape = self_dim.remove_axis(axis); + let len_to_append = remaining_shape.size() * additional; + + unsafe { + // grow backing storage and update head ptr + let data_to_array_offset = if std::mem::size_of::() != 0 { + self.as_ptr().offset_from(self.data.as_ptr()) + } else { + 0 + }; + debug_assert!(data_to_array_offset >= 0); + self.ptr = self + .data + .reserve(len_to_append) + .offset(data_to_array_offset); + } + } } /// This drops all "unreachable" elements in `self_` given the data pointer and data length. diff --git a/tests/reserve.rs b/tests/reserve.rs new file mode 100644 index 000000000..1b701d1f6 --- /dev/null +++ b/tests/reserve.rs @@ -0,0 +1,52 @@ +use ndarray::prelude::*; + +#[test] +fn reserve_1d() +{ + let mut a = Array1::::zeros((4,)); + a.reserve(Axis(0), 1000); + assert_eq!(a.shape(), &[4]); + assert!(a.into_raw_vec().capacity() >= 1004); +} + +#[test] +fn reserve_3d() +{ + let mut a = Array3::::zeros((0, 4, 8)); + a.reserve(Axis(0), 10); + assert_eq!(a.shape(), &[0, 4, 8]); + assert!(a.into_raw_vec().capacity() >= 4 * 8 * 10); +} + +#[test] +fn reserve_empty_3d() +{ + let mut a = Array3::::zeros((0, 0, 0)); + a.reserve(Axis(0), 10); +} + +#[test] +fn reserve_3d_axis1() +{ + let mut a = Array3::::zeros((2, 4, 8)); + a.reserve(Axis(1), 10); + assert!(a.into_raw_vec().capacity() >= 2 * 8 * 10); +} + +#[test] +fn reserve_3d_repeat() +{ + let mut a = Array3::::zeros((2, 4, 8)); + a.reserve(Axis(1), 10); + a.reserve(Axis(2), 30); + assert!(a.into_raw_vec().capacity() >= 2 * 4 * 30); +} + +#[test] +fn reserve_2d_with_data() +{ + let mut a = array![[1, 2], [3, 4], [5, 6]]; + a.reserve(Axis(1), 100); + assert_eq!(a, array![[1, 2], [3, 4], [5, 6]]); + assert!(a.into_raw_vec().capacity() >= 3 * 100); +} From aa077bf56f06bdedf1bace7aa0fe173afc043c0c Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sat, 11 Mar 2023 12:06:26 +1000 Subject: [PATCH 2/9] Add benchmark for reserve() --- benches/reserve.rs | 31 +++++++++++++++++++++++++++++++ src/impl_owned_array.rs | 3 --- 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 benches/reserve.rs diff --git a/benches/reserve.rs b/benches/reserve.rs new file mode 100644 index 000000000..ea9d52e96 --- /dev/null +++ b/benches/reserve.rs @@ -0,0 +1,31 @@ +#![feature(test)] + +extern crate test; +use test::Bencher; + +use ndarray::prelude::*; + +#[bench] +fn push_reserve(bench: &mut Bencher) +{ + let ones: Array = array![1f32]; + bench.iter(|| { + let mut a: Array = array![]; + a.reserve(Axis(0), 100); + for _ in 0..100 { + a.append(Axis(0), ones.view()).unwrap(); + } + }); +} + +#[bench] +fn push_no_reserve(bench: &mut Bencher) +{ + let ones: Array = array![1f32]; + bench.iter(|| { + let mut a: Array = array![]; + for _ in 0..100 { + a.append(Axis(0), ones.view()).unwrap(); + } + }); +} diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index 3b393a6d7..aeb5c7697 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -764,9 +764,6 @@ where D: Dimension pub fn reserve(&mut self, axis: Axis, additional: usize) where D: RemoveAxis { - if additional == 0 { - return; - } let self_dim = self.raw_dim(); let remaining_shape = self_dim.remove_axis(axis); let len_to_append = remaining_shape.size() * additional; From 63062d3bc1a5433e91e2049df423daec33643fa6 Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sat, 11 Mar 2023 18:29:51 +1000 Subject: [PATCH 3/9] Add convenience functions for reserving space for rows/columns in Array2 --- src/impl_owned_array.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index aeb5c7697..70f2f229f 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -251,6 +251,44 @@ impl Array { self.append(Axis(1), column.insert_axis(Axis(1))) } + + /// Reserve capacity to grow array by at least `additional` rows. + /// + /// Existing elements of `array` are untouched and the backing storage is grown by + /// calling the underlying `reserve` method of the `OwnedRepr`. + /// + /// This is useful when pushing or appending repeatedly to an array to avoid multiple + /// allocations. + /// + /// ```rust + /// use ndarray::Array2; + /// let mut a = Array2::::zeros((2,4)); + /// a.reserve_rows(1000); + /// assert!(a.into_raw_vec().capacity() >= 4*1002); + /// ``` + pub fn reserve_rows(&mut self, additional: usize) + { + self.reserve(Axis(0), additional); + } + + /// Reserve capacity to grow array by at least `additional` columns. + /// + /// Existing elements of `array` are untouched and the backing storage is grown by + /// calling the underlying `reserve` method of the `OwnedRepr`. + /// + /// This is useful when pushing or appending repeatedly to an array to avoid multiple + /// allocations. + /// + /// ```rust + /// use ndarray::Array2; + /// let mut a = Array2::::zeros((2,4)); + /// a.reserve_columns(1000); + /// assert!(a.into_raw_vec().capacity() >= 2*1002); + /// ``` + pub fn reserve_columns(&mut self, additional: usize) + { + self.reserve(Axis(1), additional); + } } impl Array @@ -761,6 +799,7 @@ where D: Dimension /// let mut a = Array3::::zeros((0,2,4)); /// a.reserve(Axis(0), 1000); /// assert!(a.into_raw_vec().capacity() >= 2*4*1000); + /// ``` pub fn reserve(&mut self, axis: Axis, additional: usize) where D: RemoveAxis { From a16707a4ab125a7e864d4a02a535e0cbeb2774e9 Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sun, 7 May 2023 20:21:43 +1000 Subject: [PATCH 4/9] Add bounds checking and error documentation --- benches/reserve.rs | 2 +- src/impl_owned_array.rs | 47 +++++++++++++++++++++++++++++++++-------- tests/reserve.rs | 14 ++++++------ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/benches/reserve.rs b/benches/reserve.rs index ea9d52e96..14ebf9f1a 100644 --- a/benches/reserve.rs +++ b/benches/reserve.rs @@ -11,7 +11,7 @@ fn push_reserve(bench: &mut Bencher) let ones: Array = array![1f32]; bench.iter(|| { let mut a: Array = array![]; - a.reserve(Axis(0), 100); + a.reserve(Axis(0), 100).unwrap(); for _ in 0..100 { a.append(Axis(0), ones.view()).unwrap(); } diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index 70f2f229f..bfaa90531 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -260,15 +260,19 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// + /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable + /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by + /// `additional` exceeds `isize::MAX`. + /// /// ```rust /// use ndarray::Array2; /// let mut a = Array2::::zeros((2,4)); - /// a.reserve_rows(1000); + /// a.reserve_rows(1000).unwrap(); /// assert!(a.into_raw_vec().capacity() >= 4*1002); /// ``` - pub fn reserve_rows(&mut self, additional: usize) + pub fn reserve_rows(&mut self, additional: usize) -> Result<(), ShapeError> { - self.reserve(Axis(0), additional); + self.reserve(Axis(0), additional) } /// Reserve capacity to grow array by at least `additional` columns. @@ -279,15 +283,19 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// + /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable + /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by + /// `additional` exceeds `isize::MAX`. + /// /// ```rust /// use ndarray::Array2; /// let mut a = Array2::::zeros((2,4)); - /// a.reserve_columns(1000); + /// a.reserve_columns(1000).unwrap(); /// assert!(a.into_raw_vec().capacity() >= 2*1002); /// ``` - pub fn reserve_columns(&mut self, additional: usize) + pub fn reserve_columns(&mut self, additional: usize) -> Result<(), ShapeError> { - self.reserve(Axis(1), additional); + self.reserve(Axis(1), additional) } } @@ -699,7 +707,7 @@ where D: Dimension }; // grow backing storage and update head ptr - self.reserve(axis, array_dim[axis.index()]); + self.reserve(axis, array_dim[axis.index()])?; unsafe { // clone elements from view to the array now @@ -788,25 +796,42 @@ where D: Dimension /// Reserve capacity to grow array along `axis` by at least `additional` elements. /// + /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the + /// number of dimensions (axes) of the array. + /// /// Existing elements of `array` are untouched and the backing storage is grown by /// calling the underlying `reserve` method of the `OwnedRepr`. /// /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// + /// ***Panics*** if the axis is out of bounds. + /// + /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable + /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by + /// `additional` exceeds `isize::MAX`. + /// /// ```rust /// use ndarray::{Array3, Axis}; /// let mut a = Array3::::zeros((0,2,4)); - /// a.reserve(Axis(0), 1000); + /// a.reserve(Axis(0), 1000).unwrap(); /// assert!(a.into_raw_vec().capacity() >= 2*4*1000); /// ``` - pub fn reserve(&mut self, axis: Axis, additional: usize) + /// + pub fn reserve(&mut self, axis: Axis, additional: usize) -> Result<(), ShapeError> where D: RemoveAxis { + debug_assert!(axis.index() < self.ndim()); let self_dim = self.raw_dim(); let remaining_shape = self_dim.remove_axis(axis); let len_to_append = remaining_shape.size() * additional; + // Make sure new capacity is still in bounds + let mut res_dim = self_dim; + res_dim[axis.index()] += additional; + let new_len = dimension::size_of_shape_checked(&res_dim)?; + debug_assert_eq!(self.len() + len_to_append, new_len); + unsafe { // grow backing storage and update head ptr let data_to_array_offset = if std::mem::size_of::() != 0 { @@ -820,6 +845,10 @@ where D: Dimension .reserve(len_to_append) .offset(data_to_array_offset); } + + debug_assert!(self.pointer_is_inbounds()); + + Ok(()) } } diff --git a/tests/reserve.rs b/tests/reserve.rs index 1b701d1f6..cdf74dbf4 100644 --- a/tests/reserve.rs +++ b/tests/reserve.rs @@ -4,7 +4,7 @@ use ndarray::prelude::*; fn reserve_1d() { let mut a = Array1::::zeros((4,)); - a.reserve(Axis(0), 1000); + a.reserve(Axis(0), 1000).unwrap(); assert_eq!(a.shape(), &[4]); assert!(a.into_raw_vec().capacity() >= 1004); } @@ -13,7 +13,7 @@ fn reserve_1d() fn reserve_3d() { let mut a = Array3::::zeros((0, 4, 8)); - a.reserve(Axis(0), 10); + a.reserve(Axis(0), 10).unwrap(); assert_eq!(a.shape(), &[0, 4, 8]); assert!(a.into_raw_vec().capacity() >= 4 * 8 * 10); } @@ -22,14 +22,14 @@ fn reserve_3d() fn reserve_empty_3d() { let mut a = Array3::::zeros((0, 0, 0)); - a.reserve(Axis(0), 10); + a.reserve(Axis(0), 10).unwrap(); } #[test] fn reserve_3d_axis1() { let mut a = Array3::::zeros((2, 4, 8)); - a.reserve(Axis(1), 10); + a.reserve(Axis(1), 10).unwrap(); assert!(a.into_raw_vec().capacity() >= 2 * 8 * 10); } @@ -37,8 +37,8 @@ fn reserve_3d_axis1() fn reserve_3d_repeat() { let mut a = Array3::::zeros((2, 4, 8)); - a.reserve(Axis(1), 10); - a.reserve(Axis(2), 30); + a.reserve(Axis(1), 10).unwrap(); + a.reserve(Axis(2), 30).unwrap(); assert!(a.into_raw_vec().capacity() >= 2 * 4 * 30); } @@ -46,7 +46,7 @@ fn reserve_3d_repeat() fn reserve_2d_with_data() { let mut a = array![[1, 2], [3, 4], [5, 6]]; - a.reserve(Axis(1), 100); + a.reserve(Axis(1), 100).unwrap(); assert_eq!(a, array![[1, 2], [3, 4], [5, 6]]); assert!(a.into_raw_vec().capacity() >= 3 * 100); } From beb14398d29ba9c2608bd5fc3565e53e195f9350 Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sun, 7 May 2023 20:34:43 +1000 Subject: [PATCH 5/9] Check for usize overflow of new capacity --- src/impl_owned_array.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index bfaa90531..faef1d9e8 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -260,6 +260,8 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// + /// ***Panics*** if the new capacity would exceed `usize::MAX`. + /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by /// `additional` exceeds `isize::MAX`. @@ -283,6 +285,8 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// + /// ***Panics*** if the new capacity would exceed `usize::MAX`. + /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by /// `additional` exceeds `isize::MAX`. @@ -805,7 +809,7 @@ where D: Dimension /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// - /// ***Panics*** if the axis is out of bounds. + /// ***Panics*** if the axis is out of bounds or if the new capacity would exceed `usize::MAX`. /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by @@ -830,7 +834,9 @@ where D: Dimension let mut res_dim = self_dim; res_dim[axis.index()] += additional; let new_len = dimension::size_of_shape_checked(&res_dim)?; - debug_assert_eq!(self.len() + len_to_append, new_len); + + // Check whether len_to_append would cause an overflow + debug_assert_eq!(self.len().checked_add(len_to_append).unwrap(), new_len); unsafe { // grow backing storage and update head ptr From 4b022eba7c3f7243233d1c968bbf2b40de4426ab Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sun, 7 May 2023 20:47:39 +1000 Subject: [PATCH 6/9] Make sure added capacity doesn't overflow usize::MAX --- src/impl_owned_array.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index faef1d9e8..6f9acb7a2 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -828,6 +828,9 @@ where D: Dimension debug_assert!(axis.index() < self.ndim()); let self_dim = self.raw_dim(); let remaining_shape = self_dim.remove_axis(axis); + + // Make sure added capacity doesn't overflow + debug_assert!(remaining_shape.size().checked_mul(additional).is_some()); let len_to_append = remaining_shape.size() * additional; // Make sure new capacity is still in bounds From 8e030d1075892236e82ba9d040fbd55f56338a7f Mon Sep 17 00:00:00 2001 From: ssande7 <1731652+ssande7@users.noreply.github.com> Date: Sun, 17 Mar 2024 12:16:51 +1000 Subject: [PATCH 7/9] Error on overflow when reserving --- src/impl_owned_array.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index 6f9acb7a2..393c2e075 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -260,8 +260,6 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// - /// ***Panics*** if the new capacity would exceed `usize::MAX`. - /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by /// `additional` exceeds `isize::MAX`. @@ -285,8 +283,6 @@ impl Array /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// - /// ***Panics*** if the new capacity would exceed `usize::MAX`. - /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by /// `additional` exceeds `isize::MAX`. @@ -809,7 +805,7 @@ where D: Dimension /// This is useful when pushing or appending repeatedly to an array to avoid multiple /// allocations. /// - /// ***Panics*** if the axis is out of bounds or if the new capacity would exceed `usize::MAX`. + /// ***Panics*** if the axis is out of bounds. /// /// ***Errors*** with a shape error if the resultant capacity is larger than the addressable /// bounds; that is, the product of non-zero axis lengths once `axis` has been extended by @@ -829,9 +825,11 @@ where D: Dimension let self_dim = self.raw_dim(); let remaining_shape = self_dim.remove_axis(axis); - // Make sure added capacity doesn't overflow - debug_assert!(remaining_shape.size().checked_mul(additional).is_some()); - let len_to_append = remaining_shape.size() * additional; + // Make sure added capacity doesn't overflow usize::MAX + let len_to_append = remaining_shape + .size() + .checked_mul(additional) + .ok_or(ShapeError::from_kind(ErrorKind::Overflow))?; // Make sure new capacity is still in bounds let mut res_dim = self_dim; From 25d2d04a3e7572251b822fdfa90979a4a7d6e2b6 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 6 Apr 2024 16:35:21 +0200 Subject: [PATCH 8/9] reserve: Add test with inverted axis Testing when the allocation to first element offset is nonzero. --- tests/reserve.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/reserve.rs b/tests/reserve.rs index cdf74dbf4..c220c1715 100644 --- a/tests/reserve.rs +++ b/tests/reserve.rs @@ -50,3 +50,16 @@ fn reserve_2d_with_data() assert_eq!(a, array![[1, 2], [3, 4], [5, 6]]); assert!(a.into_raw_vec().capacity() >= 3 * 100); } + +#[test] +fn reserve_2d_inverted_with_data() +{ + let mut a = array![[1, 2], [3, 4], [5, 6]]; + a.invert_axis(Axis(1)); + assert_eq!(a, array![[2, 1], [4, 3], [6, 5]]); + a.reserve(Axis(1), 100).unwrap(); + assert_eq!(a, array![[2, 1], [4, 3], [6, 5]]); + let (raw_vec, offset) = a.into_raw_vec_and_offset(); + assert!(raw_vec.capacity() >= 3 * 100); + assert_eq!(offset, Some(1)); +} From 7cc7141e23a9f19708ead4395f604d4068b21f89 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 6 Apr 2024 16:38:25 +0200 Subject: [PATCH 9/9] reserve: Update tests to use into_raw_vec_and_offset --- tests/reserve.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/reserve.rs b/tests/reserve.rs index c220c1715..108620014 100644 --- a/tests/reserve.rs +++ b/tests/reserve.rs @@ -1,12 +1,17 @@ use ndarray::prelude::*; +fn into_raw_vec_capacity(a: Array) -> usize +{ + a.into_raw_vec_and_offset().0.capacity() +} + #[test] fn reserve_1d() { let mut a = Array1::::zeros((4,)); a.reserve(Axis(0), 1000).unwrap(); assert_eq!(a.shape(), &[4]); - assert!(a.into_raw_vec().capacity() >= 1004); + assert!(into_raw_vec_capacity(a) >= 1004); } #[test] @@ -15,7 +20,7 @@ fn reserve_3d() let mut a = Array3::::zeros((0, 4, 8)); a.reserve(Axis(0), 10).unwrap(); assert_eq!(a.shape(), &[0, 4, 8]); - assert!(a.into_raw_vec().capacity() >= 4 * 8 * 10); + assert!(into_raw_vec_capacity(a) >= 4 * 8 * 10); } #[test] @@ -30,7 +35,7 @@ fn reserve_3d_axis1() { let mut a = Array3::::zeros((2, 4, 8)); a.reserve(Axis(1), 10).unwrap(); - assert!(a.into_raw_vec().capacity() >= 2 * 8 * 10); + assert!(into_raw_vec_capacity(a) >= 2 * 8 * 10); } #[test] @@ -39,7 +44,7 @@ fn reserve_3d_repeat() let mut a = Array3::::zeros((2, 4, 8)); a.reserve(Axis(1), 10).unwrap(); a.reserve(Axis(2), 30).unwrap(); - assert!(a.into_raw_vec().capacity() >= 2 * 4 * 30); + assert!(into_raw_vec_capacity(a) >= 2 * 4 * 30); } #[test] @@ -48,7 +53,7 @@ fn reserve_2d_with_data() let mut a = array![[1, 2], [3, 4], [5, 6]]; a.reserve(Axis(1), 100).unwrap(); assert_eq!(a, array![[1, 2], [3, 4], [5, 6]]); - assert!(a.into_raw_vec().capacity() >= 3 * 100); + assert!(into_raw_vec_capacity(a) >= 3 * 100); } #[test]