Skip to content

Instantly share code, notes, and snippets.

@getzdan
Last active October 30, 2017 13:04
Show Gist options
  • Save getzdan/fb4e91e19b0ee7cfa07e3387f1857651 to your computer and use it in GitHub Desktop.
Save getzdan/fb4e91e19b0ee7cfa07e3387f1857651 to your computer and use it in GitHub Desktop.
BreakAt iterator definition
import Base.Iterators: start, next, done, eltype, iteratoreltype, iteratorsize, SizeUnknown
struct BreakAt{P,I}
pred::P
itr::I
end
breakat(pred, itr) = BreakAt(pred, itr)
@inline start(b::BreakAt) = start_breakat(b.pred, b.itr)
@inline function start_breakat(pred, itr)
s = start(itr)
if !done(itr, s)
v, t = next(itr, s)
return pred(v) ? (true, v, t) : (false, v, t)
end
return (true, v, t)
end
@inline next(b::BreakAt, s) = advance_breakat(b.pred, b.itr, s)
@inline function advance_breakat(pred, itr, st)
_, v, s = st
if !done(itr, s)
w, t = next(itr, s)
return pred(w) ? (v, (true, w, t)) : (v, (false, w, t))
end
return (true, v, s)
end
@inline done(b::BreakAt, s) = s[1]
eltype(::Type{BreakAt{F,I}}) where {F, I} = eltype(I)
iteratoreltype(::Type{BreakAt{F,I}}) where {F, I} = iteratoreltype(I)
iteratorsize(::Type{<:BreakAt}) = SizeUnknown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment