Skip to content

Commit fe0555d

Browse files
committed
Add support for compound assignment
1 parent df6434b commit fe0555d

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ version = "0.4"
2222
version = "0.4"
2323
optional = true
2424

25+
26+
[features]
27+
28+
assign_ops = []

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ DOCCRATES = ndarray
33
# deps to delete the generated docs
44
RMDOCS =
55

6-
FEATURES =
6+
FEATURES = assign_ops
77

88
VERSIONS = $(patsubst %,target/VERS/%,$(DOCCRATES))
99

src/lib.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
//! or linear algebra. `Array` is a good container.
1616
//! - There is no integration with linear algebra packages (at least not yet).
1717
//!
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))]
1826

1927
#[cfg(feature = "serde")]
2028
extern crate serde;
@@ -42,6 +50,7 @@ pub use indexes::Indexes;
4250

4351
use iterators::Baseiter;
4452

53+
4554
pub mod linalg;
4655
mod arraytraits;
4756
#[cfg(feature = "serde")]
@@ -1176,6 +1185,61 @@ impl_binary_op!(BitXor, bitxor, ibitxor, ibitxor_scalar);
11761185
impl_binary_op!(Shl, shl, ishl, ishl_scalar);
11771186
impl_binary_op!(Shr, shr, ishr, ishr_scalar);
11781187

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+
11791243
impl<A: Clone + Neg<Output=A>, D: Dimension>
11801244
Array<A, D>
11811245
{

0 commit comments

Comments
 (0)