Skip to content

Commit ef40c03

Browse files
committed
Switches to macros to generate the impls for Iterator on MultiIter
1 parent dc3859c commit ef40c03

File tree

1 file changed

+138
-77
lines changed

1 file changed

+138
-77
lines changed

src/npyiter.rs

Lines changed: 138 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ pub trait MultiIterMode {}
163163

164164
impl MultiIterMode for () {}
165165

166-
pub struct RO<S> {
166+
pub struct RO<S: MultiIterMode> {
167167
structure: PhantomData<S>,
168168
}
169169

170170
impl<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

Comments
 (0)