|
15 | 15 | //! or linear algebra. `Array` is a good container.
|
16 | 16 | //! - There is no integration with linear algebra packages (at least not yet).
|
17 | 17 | //!
|
| 18 | +//! ## Crate feature flags |
| 19 | +//! |
| 20 | +//! - `assign_ops` |
| 21 | +//! - Optional, requires nightly |
| 22 | +//! - Enables the compound assignment operators |
| 23 | +//! |
| 24 | +#![cfg_attr(feature = "assign_ops", feature(augmented_assignments, |
| 25 | + op_assign_traits))] |
18 | 26 |
|
19 | 27 | #[cfg(feature = "serde")]
|
20 | 28 | extern crate serde;
|
@@ -42,6 +50,7 @@ pub use indexes::Indexes;
|
42 | 50 |
|
43 | 51 | use iterators::Baseiter;
|
44 | 52 |
|
| 53 | + |
45 | 54 | pub mod linalg;
|
46 | 55 | mod arraytraits;
|
47 | 56 | #[cfg(feature = "serde")]
|
@@ -1176,6 +1185,61 @@ impl_binary_op!(BitXor, bitxor, ibitxor, ibitxor_scalar);
|
1176 | 1185 | impl_binary_op!(Shl, shl, ishl, ishl_scalar);
|
1177 | 1186 | impl_binary_op!(Shr, shr, ishr, ishr_scalar);
|
1178 | 1187 |
|
| 1188 | +#[cfg(feature = "assign_ops")] |
| 1189 | +mod assign_ops { |
| 1190 | + use super::*; |
| 1191 | + |
| 1192 | + use std::ops::{ |
| 1193 | + AddAssign, |
| 1194 | + SubAssign, |
| 1195 | + MulAssign, |
| 1196 | + DivAssign, |
| 1197 | + RemAssign, |
| 1198 | + BitAndAssign, |
| 1199 | + BitOrAssign, |
| 1200 | + BitXorAssign, |
| 1201 | + }; |
| 1202 | + |
| 1203 | + |
| 1204 | + macro_rules! impl_assign_op { |
| 1205 | + ($trt:ident, $method:ident) => { |
| 1206 | + impl<'a, A, D, E> $trt<&'a Array<A, E>> for Array<A, D> |
| 1207 | + where A: Clone + $trt<A>, |
| 1208 | + D: Dimension, |
| 1209 | + E: Dimension, |
| 1210 | + { |
| 1211 | + /// Perform an elementwise in place arithmetic operation between **self** and **other**, |
| 1212 | + /// |
| 1213 | + /// If their shapes disagree, **other** is broadcast to the shape of **self**. |
| 1214 | + /// |
| 1215 | + /// **Panics** if broadcasting isn't possible. |
| 1216 | + fn $method(&mut self, other: &Array<A, E>) { |
| 1217 | + if self.shape() == other.shape() { |
| 1218 | + for (x, y) in self.iter_mut().zip(other.iter()) { |
| 1219 | + x.$method(y.clone()); |
| 1220 | + } |
| 1221 | + } else { |
| 1222 | + let other_iter = other.broadcast_iter_unwrap(self.dim()); |
| 1223 | + for (x, y) in self.iter_mut().zip(other_iter) { |
| 1224 | + x.$method(y.clone()); |
| 1225 | + } |
| 1226 | + } |
| 1227 | + } |
| 1228 | + } |
| 1229 | + |
| 1230 | + }; |
| 1231 | + } |
| 1232 | + |
| 1233 | + impl_assign_op!(AddAssign, add_assign); |
| 1234 | + impl_assign_op!(SubAssign, sub_assign); |
| 1235 | + impl_assign_op!(MulAssign, mul_assign); |
| 1236 | + impl_assign_op!(DivAssign, div_assign); |
| 1237 | + impl_assign_op!(RemAssign, rem_assign); |
| 1238 | + impl_assign_op!(BitAndAssign, bitand_assign); |
| 1239 | + impl_assign_op!(BitOrAssign, bitor_assign); |
| 1240 | + impl_assign_op!(BitXorAssign, bitxor_assign); |
| 1241 | +} |
| 1242 | + |
1179 | 1243 | impl<A: Clone + Neg<Output=A>, D: Dimension>
|
1180 | 1244 | Array<A, D>
|
1181 | 1245 | {
|
|
0 commit comments