4
4
//! [NpySingleIter](./struct.NpySingleIter.html) and
5
5
//! [NpyMultiIter](./struct.NpyMultiIter.html).
6
6
use crate :: array:: { PyArray , PyArrayDyn } ;
7
- use crate :: error:: NpyIterInstantiationError ;
8
7
use crate :: npyffi:: {
9
8
array:: PY_ARRAY_API ,
10
9
npy_intp, npy_uint32,
@@ -163,7 +162,7 @@ pub struct NpySingleIterBuilder<'py, T, I: IterMode> {
163
162
}
164
163
165
164
impl < ' py , T : Element > NpySingleIterBuilder < ' py , T , Readonly > {
166
- /// Make a new builder for a readonly iterator.
165
+ /// Makes a new builder for a readonly iterator.
167
166
pub fn readonly < D : ndarray:: Dimension > ( array : PyReadonlyArray < ' py , T , D > ) -> Self {
168
167
let ( array, was_writable) = array. destruct ( ) ;
169
168
Self {
@@ -176,7 +175,7 @@ impl<'py, T: Element> NpySingleIterBuilder<'py, T, Readonly> {
176
175
}
177
176
178
177
impl < ' py , T : Element > NpySingleIterBuilder < ' py , T , ReadWrite > {
179
- /// Make a new builder for a writable iterator.
178
+ /// Makes a new builder for a writable iterator.
180
179
pub fn readwrite < D : ndarray:: Dimension > ( array : & ' py PyArray < T , D > ) -> Self {
181
180
Self {
182
181
flags : NPY_ITER_READWRITE ,
@@ -188,13 +187,13 @@ impl<'py, T: Element> NpySingleIterBuilder<'py, T, ReadWrite> {
188
187
}
189
188
190
189
impl < ' py , T : Element , I : IterMode > NpySingleIterBuilder < ' py , T , I > {
191
- /// Set a flag to this builder, returning `self`.
190
+ /// Sets a flag to this builder, returning `self`.
192
191
pub fn set ( mut self , flag : NpyIterFlag ) -> Self {
193
192
self . flags |= flag. to_c_enum ( ) ;
194
193
self
195
194
}
196
195
197
- /// Create an iterator from this builder.
196
+ /// Creates an iterator from this builder.
198
197
pub fn build ( self ) -> PyResult < NpySingleIter < ' py , T , I > > {
199
198
let array_ptr = self . array . as_array_ptr ( ) ;
200
199
let iter_ptr = unsafe {
@@ -216,11 +215,50 @@ impl<'py, T: Element, I: IterMode> NpySingleIterBuilder<'py, T, I> {
216
215
}
217
216
}
218
217
219
- /// An iterator over a single array.
218
+ /// An iterator over a single array, construced by
219
+ /// [NpySingleIterBuilder](./struct.NpySingleIterBuilder.html).
220
+ /// This iterator iterates all elements in the array as `&mut T` (in case `readwrite` is used)
221
+ /// or `&T` (in case `readonly` is used).
220
222
///
221
223
/// # Example
222
224
///
225
+ /// You can use
226
+ /// [`NpySingleIterBuilder::readwrite`](./struct.NpySingleIterBuilder.html#method.readwrite)
227
+ /// to get a mutable iterator.
223
228
///
229
+ /// ```
230
+ /// use numpy::NpySingleIterBuilder;
231
+ /// let gil = pyo3::Python::acquire_gil();
232
+ /// let py = gil.python();
233
+ /// let array = numpy::PyArray::arange(py, 0, 10, 1);
234
+ /// let iter = NpySingleIterBuilder::readwrite(array).build().unwrap();
235
+ /// for (i, elem) in iter.enumerate() {
236
+ /// assert_eq!(*elem, i as i64);
237
+ /// *elem = *elem * 2; // elements are mutable
238
+ /// }
239
+ /// ```
240
+ /// Or, as a shorthand, `PyArray::iter` can be also used.
241
+ /// ```
242
+ /// # use numpy::NpySingleIterBuilder;
243
+ /// # let gil = pyo3::Python::acquire_gil();
244
+ /// # let py = gil.python();
245
+ /// # let array = numpy::PyArray::arange(py, 0, 10, 1);
246
+ /// for (i, elem) in array.iter().unwrap().enumerate() {
247
+ /// assert_eq!(*elem, i as i64);
248
+ /// *elem = *elem * 2; // elements are mutable
249
+ /// }
250
+ /// ```
251
+ /// On the other hand, immutable iterator requires [readonly array](../struct.PyReadonlyArray.html).
252
+ /// ```
253
+ /// use numpy::NpySingleIterBuilder;
254
+ /// let gil = pyo3::Python::acquire_gil();
255
+ /// let py = gil.python();
256
+ /// let array = numpy::PyArray::arange(py, 0, 1, 10);
257
+ /// let iter = NpySingleIterBuilder::readonly(array.readonly()).build().unwrap();
258
+ /// for (i, elem) in iter.enumerate() {
259
+ /// assert_eq!(*elem, i as i64);
260
+ /// }
261
+ /// ```
224
262
pub struct NpySingleIter < ' py , T , I > {
225
263
iterator : ptr:: NonNull < NpyIter > ,
226
264
iternext : unsafe extern "C" fn ( * mut NpyIter ) -> c_int ,
@@ -242,7 +280,7 @@ impl<'py, T, I> NpySingleIter<'py, T, I> {
242
280
let mut iterator = match ptr:: NonNull :: new ( iterator) {
243
281
Some ( iter) => iter,
244
282
None => {
245
- return Err ( NpyIterInstantiationError . into ( ) ) ;
283
+ return Err ( PyErr :: fetch ( py ) ) ;
246
284
}
247
285
} ;
248
286
@@ -257,7 +295,7 @@ impl<'py, T, I> NpySingleIter<'py, T, I> {
257
295
258
296
if dataptr. is_null ( ) {
259
297
unsafe { PY_ARRAY_API . NpyIter_Deallocate ( iterator. as_mut ( ) ) } ;
260
- return Err ( NpyIterInstantiationError . into ( ) ) ;
298
+ return Err ( PyErr :: fetch ( py ) ) ;
261
299
}
262
300
263
301
let iter_size = unsafe { PY_ARRAY_API . NpyIter_GetIterSize ( iterator. as_mut ( ) ) } ;
@@ -368,7 +406,7 @@ impl<'py, T: Element, S: MultiIterMode> NpyMultiIterBuilder<'py, T, S> {
368
406
}
369
407
}
370
408
371
- /// Add a writable array to the resulting iterator.
409
+ /// Adds a writable array to the resulting iterator.
372
410
pub fn add_readwrite < D : ndarray:: Dimension > (
373
411
mut self ,
374
412
array : & ' py PyArray < T , D > ,
@@ -385,7 +423,7 @@ impl<'py, T: Element, S: MultiIterMode> NpyMultiIterBuilder<'py, T, S> {
385
423
}
386
424
387
425
impl < ' py , T : Element , S : MultiIterModeWithManyArrays > NpyMultiIterBuilder < ' py , T , S > {
388
- /// Create an iterator from this builder.
426
+ /// Creates an iterator from this builder.
389
427
pub fn build ( self ) -> PyResult < NpyMultiIter < ' py , T , S > > {
390
428
let Self {
391
429
flags,
@@ -419,7 +457,34 @@ impl<'py, T: Element, S: MultiIterModeWithManyArrays> NpyMultiIterBuilder<'py, T
419
457
}
420
458
}
421
459
422
- /// Multi iterator
460
+ /// An iterator over multiple arrays, construced by
461
+ /// [NpyMultiIterBuilder](./struct.NpyMultiIterBuilder.html).
462
+ /// You can add
463
+ /// [`NpyMultiIterBuilder::add_readwrite`](./struct.NpyMultiIterBuilder.html#method.add_readwrite)
464
+ /// for adding a mutable component to the iterator, and
465
+ /// [`NpyMultiIterBuilder::add_readonly`](./struct.NpyMultiIterBuilder.html#method.add_readonly)
466
+ /// for adding a immutable one.
467
+ ///
468
+ /// # Example
469
+ ///
470
+ /// ```
471
+ /// use numpy::NpyMultiIterBuilder;
472
+ /// let gil = pyo3::Python::acquire_gil();
473
+ /// let py = gil.python();
474
+ /// let array1 = numpy::PyArray::arange(py, 0, 10, 1);
475
+ /// let array2 = numpy::PyArray::arange(py, 10, 20, 1);
476
+ /// let array3 = numpy::PyArray::arange(py, 10, 30, 2);
477
+ /// let iter = NpyMultiIterBuilder::new()
478
+ /// .add_readonly(array1.readonly())
479
+ /// .add_readwrite(array2)
480
+ /// .add_readonly(array3.readonly())
481
+ /// .build()
482
+ /// .unwrap();
483
+ /// for (i, j, k) in iter {
484
+ /// assert_eq!(*i + *j, *k);
485
+ /// *j += *i + *k; // The third element is only mutable.
486
+ /// }
487
+ /// ```
423
488
pub struct NpyMultiIter < ' py , T , S : MultiIterModeWithManyArrays > {
424
489
iterator : ptr:: NonNull < NpyIter > ,
425
490
iternext : unsafe extern "C" fn ( * mut NpyIter ) -> c_int ,
@@ -442,7 +507,7 @@ impl<'py, T, S: MultiIterModeWithManyArrays> NpyMultiIter<'py, T, S> {
442
507
let mut iterator = match ptr:: NonNull :: new ( iterator) {
443
508
Some ( ptr) => ptr,
444
509
None => {
445
- return Err ( NpyIterInstantiationError . into ( ) ) ;
510
+ return Err ( PyErr :: fetch ( py ) ) ;
446
511
}
447
512
} ;
448
513
@@ -457,7 +522,7 @@ impl<'py, T, S: MultiIterModeWithManyArrays> NpyMultiIter<'py, T, S> {
457
522
458
523
if dataptr. is_null ( ) {
459
524
unsafe { PY_ARRAY_API . NpyIter_Deallocate ( iterator. as_mut ( ) ) } ;
460
- return Err ( NpyIterInstantiationError . into ( ) ) ;
525
+ return Err ( PyErr :: fetch ( py ) ) ;
461
526
}
462
527
463
528
let iter_size = unsafe { PY_ARRAY_API . NpyIter_GetIterSize ( iterator. as_mut ( ) ) } ;
0 commit comments