Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.ndslice.iterator

This is a submodule of mir.ndslice.
Iterator is a type with a pointer like behavior. An ndslice can be created on top of an iterator using sliced .

Iterators

Iterator Name Used By
BytegroupIterator bytegroup .
CachedIterator cached , cachedGC .
ChopIterator chopped 
FieldIterator slicedField , bitwise , ndiota , and others.
FlattenedIterator flattened 
IndexIterator indexed 
IotaIterator iota 
MapIterator map 
MemberIterator member 
NeighboursIterator withNeighboursSum 
RetroIterator retro 
SliceIterator map  in composition with MapIterator for packed slices.
SlideIterator diff , pairwise , and slide .
StairsIterator stairs 
StrideIterator stride 
SubSliceIterator subSlices 
TripletIterator triplets 
ZipIterator zip 
License:
Authors:
Ilya Yaroshenko
struct IotaIterator(I) if (isIntegral!I || isPointer!I);
Step counter.
IotaIterator is used by iota .
Examples:
IotaIterator!int iota;
assert(*iota == 0);

// iteration
++iota;
assert(*iota == 1);

assert(iota[2] == 3);
assert(iota[-1] == 0);

--iota;
assert(*iota == 0);

// opBinary
assert(*(iota + 2) == 2);
assert(*(iota - 3) == -3);
assert((iota - 3) - iota == -3);

// construction
assert(*IotaIterator!int(3) == 3);
assert(iota - 1 < iota);
Examples:
int[32] data;
auto iota = IotaIterator!(int*)(data.ptr);
assert(*iota == data.ptr);

// iteration
++iota;
assert(*iota == 1 + data.ptr);

assert(iota[2] == 3 + data.ptr);
assert(iota[-1] == 0 + data.ptr);

--iota;
assert(*iota == 0 + data.ptr);

// opBinary
assert(*(iota + 2) == 2 + data.ptr);
assert(*(iota - 3) == -3 + data.ptr);
assert((iota - 3) - iota == -3);

// construction
assert(*IotaIterator!(int*)(data.ptr) == data.ptr);
assert(iota - 1 < iota);
I _index;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct RetroIterator(Iterator);
Reverse directions for an iterator.
RetroIterator is used by retro .
Examples:
IotaIterator!int iota;
RetroIterator!(IotaIterator!int) retro;

++iota;
--retro;
assert(*retro == *iota);

--iota;
++retro;
assert(*retro == *iota);

assert(retro[-7] == iota[7]);

iota += 100;
retro -= 100;
assert(*retro == *iota);

iota -= 100;
retro += 100;
assert(*retro == *iota);

assert(*(retro + 10) == *(iota - 10));

assert(retro - 1 < retro);

assert((retro - 5) - retro == -5);

iota = IotaIterator!int(3);
retro = RetroIterator!(IotaIterator!int)(iota);
assert(*retro == *iota);
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
struct StrideIterator(Iterator);
Iterates an iterator with a fixed strides.
StrideIterator is used by stride .
Examples:
IotaIterator!int iota;
StrideIterator!(IotaIterator!int) stride;
stride._stride = -3;

iota -= stride._stride;
--stride;
assert(*stride == *iota);

iota += stride._stride;
++stride;
assert(*stride == *iota);

assert(stride[7] == iota[7 * stride._stride]);

iota -= 100 * stride._stride;
stride -= 100;
assert(*stride == *iota);

iota += 100 * stride._stride;
stride += 100;
assert(*stride == *iota);

assert(*(stride + 10) == *(iota + 10 * stride._stride));

assert(stride - 1 < stride);

assert((stride - 5) - stride == -5);

iota = IotaIterator!int(3);
stride = StrideIterator!(IotaIterator!int)(3, iota);
assert(*stride == *iota);
ptrdiff_t _stride;
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
struct StrideIterator(Iterator, ptrdiff_t factor);
Iterates an iterator with a fixed strides.
StrideIterator is used by stride .
Examples:
IotaIterator!int iota;
StrideIterator!(IotaIterator!int, -3) stride;

iota -= stride._stride;
--stride;
assert(*stride == *iota);

iota += stride._stride;
++stride;
assert(*stride == *iota);

assert(stride[7] == iota[7 * stride._stride]);

iota -= 100 * stride._stride;
stride -= 100;
assert(*stride == *iota);

iota += 100 * stride._stride;
stride += 100;
assert(*stride == *iota);

assert(*(stride + 10) == *(iota + 10 * stride._stride));

assert(stride - 1 < stride);

assert((stride - 5) - stride == -5);
enum auto _stride;
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
struct ZipIterator(Iterators...) if (Iterators.length > 1);
Iterates multiple iterators in lockstep.
ZipIterator is used by zip .
Examples:
import mir.ndslice.traits: isIterator;

double[10] data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
alias ItA = IotaIterator!int;
alias ItB = double*;
alias ItZ = ZipIterator!(ItA, ItB);
auto zip = ItZ(ItA(3), data.ptr);
assert((*zip).a == 3);
assert((*zip).b == 1);

// iteration
++zip;
assert((*zip).a == 3 + 1);
assert((*zip).b == 1 + 1);
assert(&(*zip).b() == data.ptr + 1);

assert(zip[4].a == 3 + 5);
assert(zip[4].b == 1 + 5);
assert(&zip[4].b() == data.ptr + 5);

--zip;
assert((*zip).a == 3);
assert((*zip).b == 1);

assert((*(zip + 2)).a == 3 + 2);
assert((*(zip - 3)).a == 3 + -3);
assert((*(zip + 2)).b == 1 + 2);
assert((*(zip + 3 - 3)).b == 1);
assert((zip - 3).opBinary!"-"(zip) == -3);

assert(zip == zip);
assert(zip - 1 < zip);

static assert(isIterator!(ZipIterator!(double*, int*)));
static assert(isIterator!(ZipIterator!(immutable(double)*, immutable(int)*)));
Iterators _iterators;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
@property auto assumeFieldsHaveZeroShift();
Defined if at least one of Iterators has member assumeFieldsHaveZeroShift.
struct CachedIterator(Iterator, CacheIterator, FlagIterator);
Iterator _iterator;
CacheIterator _caches;
FlagIterator _flags;
@property scope auto lightScope()();
const @property scope auto lightScope()();
immutable @property scope auto lightScope()();
const @property auto lightConst()();
immutable @property @trusted auto lightImmutable()();
struct VmapIterator(Iterator, Fun);
VmapIterator is used by map .
Iterator _iterator;
Fun _fun;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
@property auto assumeFieldsHaveZeroShift();
struct MapIterator(Iterator, alias _fun);
MapIterator is used by map .
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun1)
@property auto assumeFieldsHaveZeroShift();
struct NeighboursIterator(Iterator, size_t N, alias _fun, bool around);
NeighboursIterator is used by map .
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct MemberIterator(Iterator, string member);
MemberIterator is used by member .
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct BytegroupIterator(Iterator, size_t count, DestinationType) if (count);
BytegroupIterator is used by Bytegroup  and bytegroup .
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct SlideIterator(Iterator, size_t params, alias fun) if (params > 1);
SlideIterator is used by diff  and slide .
Examples:
import mir.functional: naryFun;
auto data = [1, 3, 8, 18];
auto diff = SlideIterator!(int*, 2, naryFun!"b - a")(data.ptr);
assert(*diff == 2);
assert(diff[1] == 5);
assert(diff[2] == 10);
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun1)
struct IndexIterator(Iterator, Field);
Iterates a field using an iterator.
IndexIterator is used by indexed .
Iterator _iterator;
Field _field;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
struct SubSliceIterator(Iterator, Sliceable);
Iterates chunks in a sliceable using an iterator composed of indices.

Definition

auto index = iterator[i];
auto elem  = sliceable[index[0] .. index[1]];

Iterator _iterator;
Sliceable _sliceable;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct ChopIterator(Iterator, Sliceable);
Iterates chunks in a sliceable using an iterator composed of indices stored consequently.

Definition

auto elem  = _sliceable[_iterator[index] .. _iterator[index + 1]];

Iterator _iterator;
Sliceable _sliceable;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct SliceIterator(Iterator, size_t N = 1, SliceKind kind = Contiguous);
Iterates on top of another iterator and returns a slice as a multidimensional window at the current position.
SliceIterator is used by map  for packed slices.
alias Element = Slice!(Iterator, N, kind);
Element._Structure _structure;
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
struct FieldIterator(Field);
Creates an iterator on top of a field.
FieldIterator is used by slicedField , bitwise , ndiota , and others.
ptrdiff_t _index;
Field _field;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
const scope Slice!(IotaIterator!size_t) opSlice(size_t dimension)(size_t i, size_t j);
auto opIndex()(Slice!(IotaIterator!size_t) sl);
Returns:
_field[_index + sl.i .. _index + sl.j].
@property auto assumeFieldsHaveZeroShift();
struct FlattenedIterator(Iterator, size_t N, SliceKind kind) if (N > 1 && (kind == Universal || kind == Canonical));
Creates an iterator on top of all elements in a slice.
FieldIterator is used by bitwise , ndiota , and others.
ptrdiff_t[N] _indices;
Slice!(Iterator, N, kind) _slice;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
template __map(alias fun)
ref scope auto opIndexAssign(E)(ref scope E elem, size_t index) return;
struct StairsIterator(Iterator, string direction) if (direction == "+" || direction == "-");
StairsIterator is used by stairs .
Examples:
// 0
// 1 2
// 3 4 5
// 6 7 8 9
// 10 11 12 13 14
auto it = StairsIterator!(IotaIterator!size_t, "+")(1, IotaIterator!size_t());
assert(*it == [0]);
assert(it[4] == [10, 11, 12, 13, 14]);
assert(*(it + 4) == [10, 11, 12, 13, 14]);
++it;
assert(*it == [1, 2]);
it += 3;
assert(*it == [10, 11, 12, 13, 14]);
assert(it[-3] == [1, 2]);
assert(*(it - 3) == [1, 2]);
assert(it + 1 > it);
assert(it + 1 - 1 == it);
assert(it - 3 - it == -3);
--it;
assert(*it == [6, 7, 8, 9]);
Examples:
// [0, 1, 2, 3, 4],
//    [5, 6, 7, 8],
//     [9, 10, 11],
//        [12, 13],
//            [14]]);

auto it = StairsIterator!(IotaIterator!size_t, "-")(5, IotaIterator!size_t());
assert(*it == [0, 1, 2, 3, 4]);
assert(it[4] == [14]);
assert(*(it + 4) == [14]);
++it;
assert(*it == [5, 6, 7, 8]);
it += 3;
assert(*it == [14]);
assert(it[-3] == [5, 6, 7, 8]);
assert(*(it - 3) == [5, 6, 7, 8]);
assert(it + 1 > it);
assert(it + 1 - 1 == it);
assert(it - 3 - it == -3);
--it;
assert(*it == [12, 13]);
size_t _length;
Iterator _iterator;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
Slice!Iterator opUnary(string op : "*")();
Slice!Iterator opIndex()(ptrdiff_t index);
struct Triplet(Iterator, SliceKind kind = Contiguous);
Element type of TripletIterator.
size_t _iterator;
Slice!(Iterator, 1, kind) _slice;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
ref auto center();
Slice!(Iterator, 1, kind) left();
Slice!(Iterator, 1, kind) right();
struct TripletIterator(Iterator, SliceKind kind = Contiguous);
Iterates triplets position in a slice.
TripletIterator is used by triplets .
size_t _iterator;
Slice!(Iterator, 1, kind) _slice;
const @property auto lightConst()();
immutable @property auto lightImmutable()();
Triplet!(Iterator, kind) opUnary(string op : "*")();
Triplet!(Iterator, kind) opIndex()(ptrdiff_t index);