Skip to main content

RIterator

Trait RIterator 

Source
pub trait RIterator {
    type Item;

    // Required methods
    fn next(&self) -> Nullable<Self::Item>;
    fn size_hint(&self) -> (i64, Option<i64>);

    // Provided methods
    fn count(&self) -> i64 { ... }
    fn collect_n(&self, n: i32) -> Vec<Self::Item> { ... }
    fn skip(&self, n: i32) -> i32 { ... }
    fn nth(&self, n: i32) -> Nullable<Self::Item> { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_next_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_size_hint_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_count_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_collect_n_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_skip_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... }
#[doc(hidden)]
unsafe extern "C" fn __RIterator_nth_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR { ... } }
Expand description

Adapter trait for std::iter::Iterator.

Provides iterator operations for R, allowing Rust iterators to be consumed element-by-element from R code. Since iterators are stateful, the wrapper type should use interior mutability (e.g., RefCell).

§Methods

  • next() (next_item() in R) - Get the next element, or None if exhausted
  • size_hint() - Get estimated remaining elements as list(lower, upper)
  • count() - Consume and count remaining elements
  • collect_n(n) - Collect up to n elements into a vector
  • skip(n) - Skip n elements
  • nth(n) - Get the nth element (0-indexed)

§Example

ⓘ
use miniextendr_api::Nullable;
use miniextendr_api::adapter_traits::RIterator;
use std::cell::RefCell;

#[derive(ExternalPtr)]
struct MyIter(RefCell<std::vec::IntoIter<i32>>);

#[miniextendr(env)]
impl MyIter {
    fn new(data: Vec<i32>) -> Self {
        Self(RefCell::new(data.into_iter()))
    }
}

// An impl with a body inherits the trait's R names; each method here
// forwards to the cell.
#[miniextendr(env)]
impl miniextendr_api::adapter_traits::RIterator for MyIter {
    type Item = i32;

    fn next(&self) -> Nullable<i32> {
        self.0.next()
    }

    fn size_hint(&self) -> (i64, Option<i64>) {
        self.0.size_hint()
    }

    fn count(&self) -> i64 {
        self.0.count()
    }

    fn collect_n(&self, n: i32) -> Vec<i32> {
        self.0.collect_n(n)
    }

    fn skip(&self, n: i32) -> i32 {
        self.0.skip(n)
    }

    fn nth(&self, n: i32) -> Nullable<i32> {
        self.0.nth(n)
    }
}

In R (next is a reserved word, so the method is next_item):

it <- MyIter$new(c(1L, 2L, 3L))
it$RIterator$next_item()   # 1L
it$RIterator$next_item()   # 2L
it$RIterator$size_hint()   # list(1L, 1L) - one element remaining
it$RIterator$collect_n(5L) # 3L
it$RIterator$next_item()   # NULL (exhausted)

§Design Note

Every RefCell<I> with I: Iterator implements this trait. The cell supplies mutable access without erasing the iterator or restricting its item type. A concrete ExternalPtr class can delegate to its cell. This also covers standard-library adapters, itertools adapters and distribution iterators.

The blanket implementation forwards nth to the iterator, retaining its specialized implementation. It follows the source’s exhaustion behavior; use Iterator::fuse when None must be permanent.

Required Associated Types§

Source

type Item

The type of elements yielded by this iterator.

Required Methods§

Source

fn next(&self) -> Nullable<Self::Item>

Get the next element from the iterator.

Returns Nullable(Some(item)) while there are elements, and Nullable(None) once exhausted, which R receives as NULL whatever the item type: an NA could be an item, NULL never is.

Source

fn size_hint(&self) -> (i64, Option<i64>)

Get the estimated number of remaining elements.

Returns (lower_bound, upper_bound) where upper_bound is None if unknown. In R, this becomes list(lower, upper) where upper is NA if unknown.

Provided Methods§

Source

fn count(&self) -> i64

Consume the iterator and count remaining elements.

Warning: This exhausts the iterator.

Source

fn collect_n(&self, n: i32) -> Vec<Self::Item>

Collect up to n elements into a vector.

Returns fewer than n elements if the iterator is exhausted first.

Source

fn skip(&self, n: i32) -> i32

Skip n elements from the iterator.

Returns the number of elements actually skipped (may be less than n if the iterator is exhausted).

Source

fn nth(&self, n: i32) -> Nullable<Self::Item>

Get the nth element (0-indexed), consuming elements up to and including it.

Returns Nullable(None) (NULL in R) if n is negative or the iterator has fewer than n + 1 elements.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_next_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::next.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_size_hint_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::size_hint.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_count_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::count.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_collect_n_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::collect_n.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_skip_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::skip.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Source

#[doc(hidden)]
unsafe extern "C" fn __RIterator_nth_shim( data: *mut c_void, argc: i32, argv: *const SEXP, ) -> SEXP
where Nullable<<Self as RIterator>::Item>: IntoR, Vec<<Self as RIterator>::Item>: IntoR, Self: Sized + RIterator + IntoR,

Method shim for RIterator::nth.

Converts SEXP arguments, calls the method, and returns SEXP result. Both Rust panics and R longjmps are caught via with_r_unwind_protect.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<I: Iterator> RIterator for RefCell<I>

Source§

type Item = <I as Iterator>::Item

Source§

fn next(&self) -> Nullable<Self::Item>

Source§

fn size_hint(&self) -> (i64, Option<i64>)

Source§

fn count(&self) -> i64

Source§

fn collect_n(&self, n: i32) -> Vec<Self::Item>

Source§

fn skip(&self, n: i32) -> i32

Source§

fn nth(&self, n: i32) -> Nullable<Self::Item>

Implementors§