|
9 | 9 | #[macro_use]
|
10 | 10 | mod zipmacro;
|
11 | 11 |
|
| 12 | +use std::mem::MaybeUninit; |
| 13 | + |
12 | 14 | use crate::imp_prelude::*;
|
| 15 | +use crate::AssignElem; |
13 | 16 | use crate::IntoDimension;
|
14 | 17 | use crate::Layout;
|
15 | 18 | use crate::NdIndex;
|
16 | 19 |
|
17 | 20 | use crate::indexes::{indices, Indices};
|
18 |
| -use crate::layout::LayoutPriv; |
19 | 21 | use crate::layout::{CORDER, FORDER};
|
20 | 22 |
|
21 | 23 | /// Return if the expression is a break value.
|
@@ -579,6 +581,7 @@ pub struct Zip<Parts, D> {
|
579 | 581 | layout: Layout,
|
580 | 582 | }
|
581 | 583 |
|
| 584 | + |
582 | 585 | impl<P, D> Zip<(P,), D>
|
583 | 586 | where
|
584 | 587 | D: Dimension,
|
@@ -735,6 +738,12 @@ where
|
735 | 738 | self.dimension[unroll_axis] = inner_len;
|
736 | 739 | FoldWhile::Continue(acc)
|
737 | 740 | }
|
| 741 | + |
| 742 | + pub(crate) fn uninitalized_for_current_layout<T>(&self) -> Array<MaybeUninit<T>, D> |
| 743 | + { |
| 744 | + let is_f = !self.layout.is(CORDER) && self.layout.is(FORDER); |
| 745 | + Array::maybe_uninit(self.dimension.clone().set_f(is_f)) |
| 746 | + } |
738 | 747 | }
|
739 | 748 |
|
740 | 749 | /*
|
@@ -982,6 +991,42 @@ macro_rules! map_impl {
|
982 | 991 | dimension: self.dimension,
|
983 | 992 | }
|
984 | 993 | }
|
| 994 | + |
| 995 | + /// Apply and collect the results into a new array, which has the same size as the |
| 996 | + /// inputs. |
| 997 | + /// |
| 998 | + /// If all inputs are c- or f-order respectively, that is preserved in the output. |
| 999 | + /// |
| 1000 | + /// Restricted to functions that produce copyable results for technical reasons; other |
| 1001 | + /// cases are not yet implemented. |
| 1002 | + pub fn apply_collect<R>(self, f: impl FnMut($($p::Item,)* ) -> R) -> Array<R, D> |
| 1003 | + where R: Copy, |
| 1004 | + { |
| 1005 | + // To support non-Copy elements, implementation of dropping partial array (on |
| 1006 | + // panic) is needed |
| 1007 | + let mut output = self.uninitalized_for_current_layout::<R>(); |
| 1008 | + self.apply_assign_into(&mut output, f); |
| 1009 | + unsafe { |
| 1010 | + output.assume_init() |
| 1011 | + } |
| 1012 | + } |
| 1013 | + |
| 1014 | + /// Apply and assign the results into the producer `into`, which should have the same |
| 1015 | + /// size as the other inputs. |
| 1016 | + /// |
| 1017 | + /// The producer should have assignable items as dictated by the `AssignElem` trait, |
| 1018 | + /// for example `&mut R`. |
| 1019 | + pub fn apply_assign_into<R, Q>(self, into: Q, mut f: impl FnMut($($p::Item,)* ) -> R) |
| 1020 | + where Q: IntoNdProducer<Dim=D>, |
| 1021 | + Q::Item: AssignElem<R> |
| 1022 | + { |
| 1023 | + self.and(into) |
| 1024 | + .apply(move |$($p, )* output_| { |
| 1025 | + output_.assign_elem(f($($p ),*)); |
| 1026 | + }); |
| 1027 | + } |
| 1028 | + |
| 1029 | + |
985 | 1030 | );
|
986 | 1031 |
|
987 | 1032 | /// Split the `Zip` evenly in two.
|
|
0 commit comments