Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/std/iter.nct

iter.nct

//! Allocation-free readonly iteration over contiguous views.
//!
//! ViewIter retains the source view itself so element borrows preserve the
//! view's storage origin. Iterator names are ordinary standard-library APIs.

pub use std/iter/core.{
    ExactSizeIterator,
    ChainIter,
    EnumerateIter,
    FilterIter,
    FoldStep,
    Indexed,
    IntoIterator,
    Iterable,
    Iterator,
    MapIter,
    SkipIter,
    TakeIter,
    chain,
    enumerate,
    filter,
    map,
    skip,
    take,
}

/// A forward cursor over readonly borrows into contiguous storage.
pub struct ViewIter<T> {
    view: &[T]
    next_index: usize
}

construct ViewIter<T> {
    /// Creates an allocation-free readonly iterator over `view`.
    pub default func from_view(view: &[T]): Self from view {
        return ViewIter<T> {
            view: view,
            next_index: 0,
        }
    }
}

pub func from_view<T>(view: &[T]): ViewIter<T> from view {
    return ViewIter.from_view(view)
}

pub func remaining<T>(iterator: &ViewIter<T>): usize {
    return iterator.view.len() - iterator.next_index
}

pub func next<T>(iterator: &+ViewIter<T>): &T? from iterator {
    if iterator.next_index >= iterator.view.len() {
        return none
    }
    let index: usize = iterator.next_index
    iterator.next_index = index + 1
    return &iterator.view[index]
}

impl<T> ViewIter<T> {
    /// Returns the number of elements not yet yielded.
    pub method &self.remaining(): usize {
        return remaining(self)
    }

}

impl<T> ExactSizeIterator<&T> for ViewIter<T> {
    /// Implements exact-size iteration for compiler-owned element packs.
    method &self.remaining_len(): usize {
        return remaining(self)
    }
}

impl<T> Iterator<&T> for ViewIter<T> {
    /// Advances and returns a readonly borrow, or `none` at exhaustion.
    method &+self.next(): &T? from self {
        if self.next_index >= self.view.len() {
            return none
        }
        let index: usize = self.next_index
        self.next_index = index + 1
        return &self.view[index]
    }
}