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" ) ]
@@ -1102,18 +1111,18 @@ impl<A, D> Array<A, D> where
1102
1111
}
1103
1112
}
1104
1113
1105
- impl <' a, A , D , E > $trt<Array <A , E >> for Array <A , D > where
1106
- A : Clone + $trt<A , Output =A >,
1107
- D : Dimension ,
1108
- E : Dimension ,
1114
+ /// Perform an elementwise arithmetic operation between **self** and **other**,
1115
+ /// and return the result.
1116
+ ///
1117
+ /// If their shapes disagree, **other** is broadcast to the shape of **self**.
1118
+ ///
1119
+ /// **Panics** if broadcasting isn't possible.
1120
+ impl <' a, A , D , E > $trt<Array <A , E >> for Array <A , D >
1121
+ where A : Clone + $trt<A , Output =A >,
1122
+ D : Dimension ,
1123
+ E : Dimension ,
1109
1124
{
1110
1125
type Output = Array <A , D >;
1111
- /// Perform an elementwise arithmetic operation between **self** and **other**,
1112
- /// and return the result.
1113
- ///
1114
- /// If their shapes disagree, **other** is broadcast to the shape of **self**.
1115
- ///
1116
- /// **Panics** if broadcasting isn't possible.
1117
1126
fn $mth ( mut self , other: Array <A , E >) -> Array <A , D >
1118
1127
{
1119
1128
// FIXME: Can we co-broadcast arrays here? And how?
@@ -1131,18 +1140,18 @@ impl<'a, A, D, E> $trt<Array<A, E>> for Array<A, D> where
1131
1140
}
1132
1141
}
1133
1142
1134
- impl <' a, A , D , E > $trt<& ' a Array <A , E >> for & ' a Array <A , D > where
1135
- A : Clone + $trt<A , Output =A >,
1136
- D : Dimension ,
1137
- E : Dimension ,
1143
+ /// Perform an elementwise arithmetic operation between **self** and **other**,
1144
+ /// and return the result.
1145
+ ///
1146
+ /// If their shapes disagree, **other** is broadcast to the shape of **self**.
1147
+ ///
1148
+ /// **Panics** if broadcasting isn't possible.
1149
+ impl <' a, A , D , E > $trt<& ' a Array <A , E >> for & ' a Array <A , D >
1150
+ where A : Clone + $trt<A , Output =A >,
1151
+ D : Dimension ,
1152
+ E : Dimension ,
1138
1153
{
1139
1154
type Output = Array <A , D >;
1140
- /// Perform an elementwise arithmetic operation between **self** and **other**,
1141
- /// and return the result.
1142
- ///
1143
- /// If their shapes disagree, **other** is broadcast to the shape of **self**.
1144
- ///
1145
- /// **Panics** if broadcasting isn't possible.
1146
1155
fn $mth ( self , other: & ' a Array <A , E >) -> Array <A , D >
1147
1156
{
1148
1157
// FIXME: Can we co-broadcast arrays here? And how?
@@ -1176,6 +1185,64 @@ 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
+
1207
+ /// Perform an elementwise in place arithmetic operation between **self** and **other**,
1208
+ ///
1209
+ /// If their shapes disagree, **other** is broadcast to the shape of **self**.
1210
+ ///
1211
+ /// **Panics** if broadcasting isn't possible.
1212
+ ///
1213
+ /// **Requires `feature = "assign_ops"`**
1214
+ impl <' a, A , D , E > $trt<& ' a Array <A , E >> for Array <A , D >
1215
+ where A : Clone + $trt<A >,
1216
+ D : Dimension ,
1217
+ E : Dimension ,
1218
+ {
1219
+ fn $method( & mut self , other: & Array <A , E >) {
1220
+ if self . shape( ) == other. shape( ) {
1221
+ for ( x, y) in self . iter_mut( ) . zip( other. iter( ) ) {
1222
+ x. $method( y. clone( ) ) ;
1223
+ }
1224
+ } else {
1225
+ let other_iter = other. broadcast_iter_unwrap( self . dim( ) ) ;
1226
+ for ( x, y) in self . iter_mut( ) . zip( other_iter) {
1227
+ x. $method( y. clone( ) ) ;
1228
+ }
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ } ;
1234
+ }
1235
+
1236
+ impl_assign_op ! ( AddAssign , add_assign) ;
1237
+ impl_assign_op ! ( SubAssign , sub_assign) ;
1238
+ impl_assign_op ! ( MulAssign , mul_assign) ;
1239
+ impl_assign_op ! ( DivAssign , div_assign) ;
1240
+ impl_assign_op ! ( RemAssign , rem_assign) ;
1241
+ impl_assign_op ! ( BitAndAssign , bitand_assign) ;
1242
+ impl_assign_op ! ( BitOrAssign , bitor_assign) ;
1243
+ impl_assign_op ! ( BitXorAssign , bitxor_assign) ;
1244
+ }
1245
+
1179
1246
impl < A : Clone + Neg < Output =A > , D : Dimension >
1180
1247
Array < A , D >
1181
1248
{
0 commit comments