@@ -163,13 +163,13 @@ pub trait MultiIterMode {}
163163
164164impl MultiIterMode for ( ) { }
165165
166- pub struct RO < S > {
166+ pub struct RO < S : MultiIterMode > {
167167 structure : PhantomData < S > ,
168168}
169169
170170impl < S : MultiIterMode > MultiIterMode for RO < S > { }
171171
172- pub struct RW < S > {
172+ pub struct RW < S : MultiIterMode > {
173173 structure : PhantomData < S > ,
174174}
175175
@@ -318,94 +318,155 @@ impl<'py, T, S: MultiIterModeHasManyArrays> Drop for NpyMultiIterArray<'py, T, S
318318 }
319319}
320320
321- impl < ' py , T : ' py > std:: iter:: Iterator for NpyMultiIterArray < ' py , T , RO < RO < ( ) > > > {
322- type Item = ( & ' py T , & ' py T ) ;
321+ macro_rules! implement_iter_on_type {
322+ ( $arg: ty, $ty: ty, $arg_name: ident, $sol: expr ) =>
323+ {
324+ impl <' py, T : ' py> std:: iter:: Iterator for NpyMultiIterArray <' py, T , $arg> {
325+ type Item = $ty;
323326
324- fn next ( & mut self ) -> Option < Self :: Item > {
325- if self . empty {
327+ fn next( & mut $arg_name ) -> Option <Self :: Item > {
328+ if $arg_name . empty {
326329 None
327330 } else {
328331 // Note: This pointer is correct and doesn't need to be updated,
329332 // note that we're derefencing a **char into a *char casting to a *T
330333 // and then transforming that into a reference, the value that dataptr
331334 // points to is being updated by iternext to point to the next value.
332335 let retval = Some ( unsafe {
333- (
334- & * ( * self . dataptr as * mut T ) ,
335- & * ( * self . dataptr . offset ( 1 ) as * mut T ) ,
336- )
336+ $sol
337337 } ) ;
338- self . empty = unsafe { ( self . iternext ) ( self . iterator . as_mut ( ) ) } == 0 ;
338+ $arg_name . empty = unsafe { ( $arg_name . iternext) ( $arg_name . iterator. as_mut( ) ) } == 0 ;
339339 retval
340340 }
341341 }
342342}
343-
344- impl < ' py , T : ' py > std:: iter:: Iterator for NpyMultiIterArray < ' py , T , RO < RW < ( ) > > > {
345- type Item = ( & ' py mut T , & ' py T ) ;
346-
347- fn next ( & mut self ) -> Option < Self :: Item > {
348- if self . empty {
349- None
350- } else {
351- // Note: This pointer is correct and doesn't need to be updated,
352- // note that we're derefencing a **char into a *char casting to a *T
353- // and then transforming that into a reference, the value that dataptr
354- // points to is being updated by iternext to point to the next value.
355- let retval = Some ( unsafe {
356- (
357- & mut * ( * self . dataptr as * mut T ) ,
358- & * ( * self . dataptr . offset ( 1 ) as * mut T ) ,
359- )
360- } ) ;
361- self . empty = unsafe { ( self . iternext ) ( self . iterator . as_mut ( ) ) } == 0 ;
362- retval
363- }
364343 }
365344}
366345
367- impl < ' py , T : ' py > std:: iter:: Iterator for NpyMultiIterArray < ' py , T , RW < RO < ( ) > > > {
368- type Item = ( & ' py T , & ' py mut T ) ;
369-
370- fn next ( & mut self ) -> Option < Self :: Item > {
371- if self . empty {
372- None
373- } else {
374- // Note: This pointer is correct and doesn't need to be updated,
375- // note that we're derefencing a **char into a *char casting to a *T
376- // and then transforming that into a reference, the value that dataptr
377- // points to is being updated by iternext to point to the next value.
378- let retval = Some ( unsafe {
379- (
380- & * ( * self . dataptr as * mut T ) ,
381- & mut * ( * self . dataptr . offset ( 1 ) as * mut T ) ,
382- )
383- } ) ;
384- self . empty = unsafe { ( self . iternext ) ( self . iterator . as_mut ( ) ) } == 0 ;
385- retval
386- }
387- }
388- }
389-
390- impl < ' py , T : ' py > std:: iter:: Iterator for NpyMultiIterArray < ' py , T , RW < RW < ( ) > > > {
391- type Item = ( & ' py mut T , & ' py mut T ) ;
392-
393- fn next ( & mut self ) -> Option < Self :: Item > {
394- if self . empty {
395- None
396- } else {
397- // Note: This pointer is correct and doesn't need to be updated,
398- // note that we're derefencing a **char into a *char casting to a *T
399- // and then transforming that into a reference, the value that dataptr
400- // points to is being updated by iternext to point to the next value.
401- let retval = Some ( unsafe {
402- (
403- & mut * ( * self . dataptr as * mut T ) ,
404- & mut * ( * self . dataptr . offset ( 1 ) as * mut T ) ,
405- )
406- } ) ;
407- self . empty = unsafe { ( self . iternext ) ( self . iterator . as_mut ( ) ) } == 0 ;
408- retval
409- }
410- }
411- }
346+ implement_iter_on_type ! (
347+ RO <RO <( ) >>,
348+ ( & ' py T , & ' py T ) ,
349+ self ,
350+ (
351+ & * ( * self . dataptr as * mut T ) ,
352+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
353+ )
354+ ) ;
355+
356+ implement_iter_on_type ! (
357+ RO <RW <( ) >>,
358+ ( & ' py mut T , & ' py T ) ,
359+ self ,
360+ (
361+ & mut * ( * self . dataptr as * mut T ) ,
362+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
363+ )
364+ ) ;
365+
366+ implement_iter_on_type ! (
367+ RW <RO <( ) >>,
368+ ( & ' py T , & ' py mut T ) ,
369+ self ,
370+ (
371+ & * ( * self . dataptr as * mut T ) ,
372+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
373+ )
374+ ) ;
375+
376+ implement_iter_on_type ! (
377+ RW <RW <( ) >>,
378+ ( & ' py mut T , & ' py mut T ) ,
379+ self ,
380+ (
381+ & mut * ( * self . dataptr as * mut T ) ,
382+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
383+ )
384+ ) ;
385+
386+ implement_iter_on_type ! (
387+ RW <RW <RW <( ) >>>,
388+ ( & ' py mut T , & ' py mut T , & ' py mut T ) ,
389+ self ,
390+ (
391+ & mut * ( * self . dataptr as * mut T ) ,
392+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
393+ & mut * ( * self . dataptr. offset( 2 ) as * mut T ) ,
394+ )
395+ ) ;
396+
397+ implement_iter_on_type ! (
398+ RW <RW <RO <( ) >>>,
399+ ( & ' py T , & ' py mut T , & ' py mut T ) ,
400+ self ,
401+ (
402+ & * ( * self . dataptr as * mut T ) ,
403+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
404+ & mut * ( * self . dataptr. offset( 2 ) as * mut T ) ,
405+ )
406+ ) ;
407+
408+ implement_iter_on_type ! (
409+ RW <RO <RW <( ) >>>,
410+ ( & ' py mut T , & ' py T , & ' py mut T ) ,
411+ self ,
412+ (
413+ & mut * ( * self . dataptr as * mut T ) ,
414+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
415+ & mut * ( * self . dataptr. offset( 2 ) as * mut T ) ,
416+ )
417+ ) ;
418+
419+ implement_iter_on_type ! (
420+ RO <RW <RW <( ) >>>,
421+ ( & ' py mut T , & ' py mut T , & ' py T ) ,
422+ self ,
423+ (
424+ & mut * ( * self . dataptr as * mut T ) ,
425+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
426+ & * ( * self . dataptr. offset( 2 ) as * mut T ) ,
427+ )
428+ ) ;
429+
430+ implement_iter_on_type ! (
431+ RW <RO <RO <( ) >>>,
432+ ( & ' py T , & ' py T , & ' py mut T ) ,
433+ self ,
434+ (
435+ & * ( * self . dataptr as * mut T ) ,
436+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
437+ & mut * ( * self . dataptr. offset( 2 ) as * mut T ) ,
438+ )
439+ ) ;
440+
441+ implement_iter_on_type ! (
442+ RO <RW <RO <( ) >>>,
443+ ( & ' py T , & ' py mut T , & ' py T ) ,
444+ self ,
445+ (
446+ & * ( * self . dataptr as * mut T ) ,
447+ & mut * ( * self . dataptr. offset( 1 ) as * mut T ) ,
448+ & * ( * self . dataptr. offset( 2 ) as * mut T ) ,
449+ )
450+ ) ;
451+
452+ implement_iter_on_type ! (
453+ RO <RO <RW <( ) >>>,
454+ ( & ' py mut T , & ' py T , & ' py T ) ,
455+ self ,
456+ (
457+ & mut * ( * self . dataptr as * mut T ) ,
458+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
459+ & * ( * self . dataptr. offset( 2 ) as * mut T ) ,
460+ )
461+ ) ;
462+
463+ implement_iter_on_type ! (
464+ RO <RO <RO <( ) >>>,
465+ ( & ' py T , & ' py T , & ' py T ) ,
466+ self ,
467+ (
468+ & * ( * self . dataptr as * mut T ) ,
469+ & * ( * self . dataptr. offset( 1 ) as * mut T ) ,
470+ & * ( * self . dataptr. offset( 2 ) as * mut T ) ,
471+ )
472+ ) ;
0 commit comments