diff --git a/src/impl_constructors.rs b/src/impl_constructors.rs index 63688ea7f..d082a5ce3 100644 --- a/src/impl_constructors.rs +++ b/src/impl_constructors.rs @@ -531,30 +531,14 @@ where /// // two first columns in b are two last in a /// // rest of columns in b are the initial columns in a /// - /// assign_to(a.slice(s![.., -2..]), b.slice_mut(s![.., ..2])); - /// assign_to(a.slice(s![.., 2..]), b.slice_mut(s![.., ..-2])); + /// a.slice(s![.., -2..]).assign_to(b.slice_mut(s![.., ..2])); + /// a.slice(s![.., 2..]).assign_to(b.slice_mut(s![.., ..-2])); /// /// // Now we can promise that `b` is safe to use with all operations /// unsafe { /// b.assume_init() /// } /// } - /// - /// use ndarray::{IntoNdProducer, AssignElem}; - /// - /// // This function clones elements from the first input to the second; - /// // the two producers must have the same shape - /// fn assign_to<'a, P1, P2, A>(from: P1, to: P2) - /// where P1: IntoNdProducer, - /// P2: IntoNdProducer, - /// P2::Item: AssignElem, - /// A: Clone + 'a - /// { - /// Zip::from(from) - /// .map_assign_into(to, A::clone); - /// } - /// - /// # shift_by_two(&Array2::zeros((8, 8))); /// ``` pub fn uninit(shape: Sh) -> ArrayBase where diff --git a/src/impl_methods.rs b/src/impl_methods.rs index d039d68a6..5b17c817d 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -15,6 +15,7 @@ use rawpointer::PointerExt; use crate::imp_prelude::*; use crate::{arraytraits, DimMax}; +use crate::argument_traits::AssignElem; use crate::dimension; use crate::dimension::IntoDimension; use crate::dimension::{ @@ -25,7 +26,7 @@ use crate::dimension::broadcast::co_broadcast; use crate::error::{self, ErrorKind, ShapeError, from_kind}; use crate::math_cell::MathCell; use crate::itertools::zip; -use crate::zip::Zip; +use crate::zip::{IntoNdProducer, Zip}; use crate::AxisDescription; use crate::iter::{ @@ -2049,6 +2050,23 @@ where self.zip_mut_with(rhs, |x, y| *x = y.clone()); } + /// Perform an elementwise assigment of values cloned from `self` into array or producer `to`. + /// + /// The destination `to` can be another array or a producer of assignable elements. + /// [`AssignElem`] determines how elements are assigned. + /// + /// **Panics** if shapes disagree. + pub fn assign_to

(&self, to: P) + where + S: Data, + P: IntoNdProducer, + P::Item: AssignElem, + A: Clone, + { + Zip::from(self) + .map_assign_into(to, A::clone); + } + /// Perform an elementwise assigment to `self` from element `x`. pub fn fill(&mut self, x: A) where diff --git a/src/lib.rs b/src/lib.rs index f48da4b32..778807aff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -206,7 +206,6 @@ mod shape_builder; mod slice; mod split_at; mod stacking; -mod traversal_utils; #[macro_use] mod zip; diff --git a/src/stacking.rs b/src/stacking.rs index 580d94b43..500ded6af 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -8,7 +8,6 @@ use crate::error::{from_kind, ErrorKind, ShapeError}; use crate::imp_prelude::*; -use crate::traversal_utils::assign_to; /// Stack arrays along the new axis. /// @@ -99,7 +98,7 @@ where for array in arrays { let len = array.len_of(axis); let (front, rest) = assign_view.split_at(axis, len); - assign_to(array, front); + array.assign_to(front); assign_view = rest; } debug_assert_eq!(assign_view.len(), 0); @@ -171,7 +170,7 @@ where // but same number of axes). let assign_view = assign_view.into_dimensionality::() .expect("same-dimensionality cast"); - assign_to(array, assign_view); + array.assign_to(assign_view); }); unsafe { diff --git a/src/traversal_utils.rs b/src/traversal_utils.rs deleted file mode 100644 index 3f4d017bf..000000000 --- a/src/traversal_utils.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2020 bluss and ndarray developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use crate::{ - IntoNdProducer, - AssignElem, - Zip, -}; - -/// Assign values from producer P1 to producer P2 -/// P1 and P2 must be of the same shape and dimension -pub(crate) fn assign_to<'a, P1, P2, A>(from: P1, to: P2) - where P1: IntoNdProducer, - P2: IntoNdProducer, - P2::Item: AssignElem, - A: Clone + 'a -{ - Zip::from(from) - .map_assign_into(to, A::clone); -} - diff --git a/tests/array.rs b/tests/array.rs index fa5da4419..28e305f53 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -900,31 +900,6 @@ fn standard_layout() { assert!(x4.is_standard_layout()); } -#[test] -fn assign() { - let mut a = arr2(&[[1., 2.], [3., 4.]]); - let b = arr2(&[[1., 3.], [2., 4.]]); - a.assign(&b); - assert_eq!(a, b); - - /* Test broadcasting */ - a.assign(&ArcArray::zeros(1)); - assert_eq!(a, ArcArray::zeros((2, 2))); - - /* Test other type */ - a.assign(&Array::from_elem((2, 2), 3.)); - assert_eq!(a, ArcArray::from_elem((2, 2), 3.)); - - /* Test mut view */ - let mut a = arr2(&[[1, 2], [3, 4]]); - { - let mut v = a.view_mut(); - v.slice_collapse(s![..1, ..]); - v.fill(0); - } - assert_eq!(a, arr2(&[[0, 0], [3, 4]])); -} - #[test] fn iter_size_hint() { let mut a = arr2(&[[1., 2.], [3., 4.]]); diff --git a/tests/higher_order_f.rs b/tests/higher_order_f.rs index c567eb3e0..1238cc4d8 100644 --- a/tests/higher_order_f.rs +++ b/tests/higher_order_f.rs @@ -6,3 +6,37 @@ fn test_fold_axis_oob() { let a = arr2(&[[1., 2.], [3., 4.]]); a.fold_axis(Axis(2), 0., |x, y| x + y); } + +#[test] +fn assign() { + let mut a = arr2(&[[1., 2.], [3., 4.]]); + let b = arr2(&[[1., 3.], [2., 4.]]); + a.assign(&b); + assert_eq!(a, b); + + /* Test broadcasting */ + a.assign(&ArcArray::zeros(1)); + assert_eq!(a, ArcArray::zeros((2, 2))); + + /* Test other type */ + a.assign(&Array::from_elem((2, 2), 3.)); + assert_eq!(a, ArcArray::from_elem((2, 2), 3.)); + + /* Test mut view */ + let mut a = arr2(&[[1, 2], [3, 4]]); + { + let mut v = a.view_mut(); + v.slice_collapse(s![..1, ..]); + v.fill(0); + } + assert_eq!(a, arr2(&[[0, 0], [3, 4]])); +} + + +#[test] +fn assign_to() { + let mut a = arr2(&[[1., 2.], [3., 4.]]); + let b = arr2(&[[0., 3.], [2., 0.]]); + b.assign_to(&mut a); + assert_eq!(a, b); +}