ref: a7c11c4d0a52661a299a90b47d9a68be8e11312f
dir: /lib/std/iterutil.myr/
use "types" use "fmt" use "extremum" pkg std = type zipiter(@a, @b) = struct s1 : @a[:] s2 : @b[:] ;; type reverseiter(@a) = struct sl : @a[:] idx : size ;; type enumiter(@a) = struct idx : size sl : @a[:] ;; type refiter(@a) = struct idx : size sl : @a[:] ;; type chunkiter(@a) = struct idx : size blksz : size sl : @a[:] ;; impl iterable zipiter(@a, @b) -> (@a, @b) impl iterable enumiter(@a) -> (size, @a) impl iterable reverseiter(@a) -> @a impl iterable refiter(@a) -> @a# impl iterable chunkiter(@a) -> @a[:] generic byzip : (a : @a[:], b : @b[:] -> zipiter(@a, @b)) generic byenum : (a : @a[:] -> enumiter(@a)) generic byreverse : (sl : @a[:] -> reverseiter(@a)) generic byref : (sl : @a[:] -> reverseiter(@a)) generic bychunk : (a : @a[:], chunk : size -> chunkiter(@a)) ;; generic byzip = {a, b -> [.s1 = a, .s2 = b] } impl iterable zipiter(@a, @b) -> (@a, @b) = __iternext__ = {itp, valp if itp.s1.len > 0 && itp.s2.len > 0 valp# = (itp.s1[0], itp.s2[0]) itp.s1 = itp.s1[1:] itp.s2 = itp.s2[1:] -> true else -> false ;; } __iterfin__ = {itp, valp } ;; generic byreverse = {sl -> [.sl = sl, .idx = sl.len] } impl iterable reverseiter(@a) -> @a = __iternext__ = {itp, valp if itp.idx > 0 valp# = itp.sl[itp.idx - 1] itp.idx-- -> true else -> false ;; } __iterfin__ = {itp, valp } ;; generic byenum = {a -> [.sl = a, .idx = 0] } impl iterable enumiter(@a) -> (size, @a) = __iternext__ = {itp, valp if itp.idx == itp.sl.len -> false ;; valp# = (itp.idx, itp.sl[itp.idx]) itp.idx++ -> true } __iterfin__ = {itp, valp } ;; generic byref = {a -> [.sl = a, .idx = 0] } impl iterable refiter(@a) -> @a# = __iternext__ = {itp, valp if itp.idx == itp.sl.len -> false ;; valp# = &itp.sl[itp.idx] itp.idx++ -> true } __iterfin__ = {itp, valp } ;; generic bychunk = {a, sz -> [.sl = a, .idx = 0, .blksz = sz] } impl iterable chunkiter(@a) -> @a[:] = __iternext__ = {itp, valp var len len = min(itp.blksz, itp.sl.len - itp.idx) if itp.idx + len == itp.sl.len -> false ;; valp# = itp.sl[itp.idx: itp.idx + len] itp.idx += itp.blksz -> true } __iterfin__ = {itp, valp } ;;