@@ -283,54 +283,58 @@ macro_rules! def_array_enum {
283
283
}
284
284
}
285
285
286
- fn add( & self , other: & ArrayContentType , vm: & VirtualMachine ) -> PyResult <PyObjectRef > {
286
+ fn add( & self , other: & ArrayContentType , vm: & VirtualMachine ) -> PyResult <Self > {
287
287
match self {
288
288
$( ArrayContentType :: $n( v) => if let ArrayContentType :: $n( other) = other {
289
289
let elements = v. iter( ) . chain( other. iter( ) ) . cloned( ) . collect( ) ;
290
- let sliced = ArrayContentType :: $n( elements) ;
291
- let obj = PyArray {
292
- array: PyRwLock :: new( sliced)
293
- }
294
- . into_object( vm) ;
295
- Ok ( obj)
290
+ Ok ( ArrayContentType :: $n( elements) )
296
291
} else {
297
292
Err ( vm. new_type_error( "bad argument type for built-in operation" . to_owned( ) ) )
298
293
} , ) *
299
294
}
300
295
}
301
296
302
- fn iadd( & mut self , other: ArrayContentType , vm: & VirtualMachine ) -> PyResult <( ) > {
297
+ fn iadd( & mut self , other: & ArrayContentType , vm: & VirtualMachine ) -> PyResult <( ) > {
303
298
match self {
304
- $( ArrayContentType :: $n( v) => if let ArrayContentType :: $n( mut other) = other {
305
- v. append ( & mut other) ;
299
+ $( ArrayContentType :: $n( v) => if let ArrayContentType :: $n( other) = other {
300
+ v. extend ( other) ;
306
301
Ok ( ( ) )
307
302
} else {
308
303
Err ( vm. new_type_error( "can only extend with array of same kind" . to_owned( ) ) )
309
304
} , ) *
310
305
}
311
306
}
312
307
313
- fn mul( & self , counter: isize , vm : & VirtualMachine ) -> PyObjectRef {
308
+ fn mul( & self , counter: isize ) -> Self {
314
309
let counter = if counter < 0 { 0 } else { counter as usize } ;
315
310
match self {
316
311
$( ArrayContentType :: $n( v) => {
317
- let elements = v. iter( ) . cycle( ) . take( v. len( ) * counter) . cloned( ) . collect( ) ;
318
- let sliced = ArrayContentType :: $n( elements) ;
319
- PyArray {
320
- array: PyRwLock :: new( sliced)
321
- }
322
- . into_object( vm)
312
+ let elements = v. repeat( counter) ;
313
+ ArrayContentType :: $n( elements)
323
314
} ) *
324
315
}
325
316
}
326
317
327
- fn imul( & mut self , counter: isize ) {
328
- let counter = if counter < 0 { 0 } else { counter as usize } ;
318
+ fn clear( & mut self ) {
329
319
match self {
330
- $( ArrayContentType :: $n( v) => {
331
- let mut elements = v. iter( ) . cycle( ) . take( v. len( ) * counter) . cloned( ) . collect( ) ;
332
- std:: mem:: swap( v, & mut elements) ;
333
- } ) *
320
+ $( ArrayContentType :: $n( v) => v. clear( ) , ) *
321
+ }
322
+ }
323
+
324
+ fn imul( & mut self , counter: isize ) {
325
+ if counter <= 0 {
326
+ self . clear( ) ;
327
+ } else if counter != 1 {
328
+ let counter = counter as usize ;
329
+ match self {
330
+ $( ArrayContentType :: $n( v) => {
331
+ let old = v. clone( ) ;
332
+ v. reserve( ( counter - 1 ) * old. len( ) ) ;
333
+ for _ in 1 ..counter {
334
+ v. extend( & old) ;
335
+ }
336
+ } ) *
337
+ }
334
338
}
335
339
}
336
340
@@ -489,7 +493,7 @@ impl PyArray {
489
493
array : PyRwLock :: new ( array) ,
490
494
} ;
491
495
if let OptionalArg :: Present ( init) = init {
492
- zelf. extend ( init, vm) ?;
496
+ zelf. extend_from_iterable ( init, vm) ?;
493
497
}
494
498
zelf. into_ref_with_type ( vm, cls)
495
499
}
@@ -525,15 +529,27 @@ impl PyArray {
525
529
self . borrow_value_mut ( ) . remove ( x, vm)
526
530
}
527
531
528
- #[ pymethod]
529
- fn extend ( & self , iter : PyIterable , vm : & VirtualMachine ) -> PyResult < ( ) > {
532
+ fn extend_from_iterable ( & self , iter : PyIterable , vm : & VirtualMachine ) -> PyResult < ( ) > {
530
533
let mut array = self . borrow_value_mut ( ) ;
531
- for elem in iter. iter ( vm) ? {
532
- array. push ( elem ?, vm) ?;
534
+ for obj in iter. iter ( vm) ? {
535
+ array. push ( obj ?, vm) ?;
533
536
}
534
537
Ok ( ( ) )
535
538
}
536
539
540
+ #[ pymethod]
541
+ fn extend ( zelf : PyRef < Self > , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
542
+ if zelf. is ( & obj) {
543
+ zelf. borrow_value_mut ( ) . imul ( 2 ) ;
544
+ Ok ( ( ) )
545
+ } else if let Some ( array) = obj. payload :: < PyArray > ( ) {
546
+ zelf. borrow_value_mut ( ) . iadd ( & * array. borrow_value ( ) , vm)
547
+ } else {
548
+ let iter = PyIterable :: try_from_object ( vm, obj) ?;
549
+ zelf. extend_from_iterable ( iter, vm)
550
+ }
551
+ }
552
+
537
553
#[ pymethod]
538
554
fn frombytes ( & self , b : PyBytesRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
539
555
let b = b. borrow_value ( ) ;
@@ -670,9 +686,16 @@ impl PyArray {
670
686
}
671
687
672
688
#[ pymethod( name = "__add__" ) ]
673
- fn add ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
689
+ fn add ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
674
690
if let Some ( other) = other. payload :: < PyArray > ( ) {
675
- self . borrow_value ( ) . add ( & * other. borrow_value ( ) , vm)
691
+ self . borrow_value ( )
692
+ . add ( & * other. borrow_value ( ) , vm)
693
+ . map ( |array| {
694
+ PyArray {
695
+ array : PyRwLock :: new ( array) ,
696
+ }
697
+ . into_ref ( vm)
698
+ } )
676
699
} else {
677
700
Err ( vm. new_type_error ( format ! (
678
701
"can only append array (not \" {}\" ) to array" ,
@@ -682,11 +705,13 @@ impl PyArray {
682
705
}
683
706
684
707
#[ pymethod( name = "__iadd__" ) ]
685
- fn iadd ( zelf : PyRef < Self > , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
686
- if let Some ( other) = other. payload :: < PyArray > ( ) {
687
- let other = other. borrow_value ( ) . clone ( ) ;
688
- let result = zelf. borrow_value_mut ( ) . iadd ( other, vm) ;
689
- result. map ( |_| zelf. into_object ( ) )
708
+ fn iadd ( zelf : PyRef < Self > , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
709
+ if zelf. is ( & other) {
710
+ zelf. borrow_value_mut ( ) . imul ( 2 ) ;
711
+ Ok ( zelf)
712
+ } else if let Some ( other) = other. payload :: < PyArray > ( ) {
713
+ let result = zelf. borrow_value_mut ( ) . iadd ( & * other. borrow_value ( ) , vm) ;
714
+ result. map ( |_| zelf)
690
715
} else {
691
716
Err ( vm. new_type_error ( format ! (
692
717
"can only extend array with array (not \" {}\" )" ,
@@ -696,12 +721,15 @@ impl PyArray {
696
721
}
697
722
698
723
#[ pymethod( name = "__mul__" ) ]
699
- fn mul ( & self , counter : isize , vm : & VirtualMachine ) -> PyObjectRef {
700
- self . borrow_value ( ) . mul ( counter, vm)
724
+ fn mul ( & self , counter : isize , vm : & VirtualMachine ) -> PyRef < Self > {
725
+ PyArray {
726
+ array : PyRwLock :: new ( self . borrow_value ( ) . mul ( counter) ) ,
727
+ }
728
+ . into_ref ( vm)
701
729
}
702
730
703
731
#[ pymethod( name = "__rmul__" ) ]
704
- fn rmul ( & self , counter : isize , vm : & VirtualMachine ) -> PyObjectRef {
732
+ fn rmul ( & self , counter : isize , vm : & VirtualMachine ) -> PyRef < Self > {
705
733
self . mul ( counter, & vm)
706
734
}
707
735
0 commit comments