From a9d1355891b5d8a951d5f5082b5ad832979580bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciara=CC=81n=20O=E2=80=99Mara?= Date: Sat, 29 Jan 2022 10:07:48 +1100 Subject: [PATCH] Loosen search iterator --- src/BioSequences.jl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/BioSequences.jl b/src/BioSequences.jl index a1cdd414..d85454ff 100644 --- a/src/BioSequences.jl +++ b/src/BioSequences.jl @@ -229,7 +229,8 @@ include("search/pwm.jl") -struct Search{Q,I} +struct Search{F,Q,I} + findfunc::F query::Q itr::I overlap::Bool @@ -237,18 +238,25 @@ end const DEFAULT_OVERLAP = true -search(query, itr; overlap = DEFAULT_OVERLAP) = Search(query, itr, overlap) +search(query, itr; overlap = DEFAULT_OVERLAP, rev=false) = Search(rev ? findprev : findnext, query, itr, overlap) -function Base.iterate(itr::Search, state=firstindex(itr.itr)) - val = findnext(itr.query, itr.itr, state) +function Base.iterate(itr::Search{typeof(findnext)}, state=firstindex(itr.itr)) + val = itr.findfunc(itr.query, itr.itr, state) val === nothing && return nothing state = itr.overlap ? first(val) + 1 : last(val) + 1 return val, state end +function Base.iterate(itr::Search{typeof(findprev)}, state=firstindex(itr.itr)) + val = itr.findfunc(itr.query, itr.itr, state) + val === nothing && return nothing + state = itr.overlap ? last(val) - 1 : first(val) - 1 + return val, state +end + const HasRangeEltype = Union{<:ExactSearchQuery, <:ApproximateSearchQuery, <:Regex} -Base.eltype(::Type{<:Search{Q}}) where {Q<:HasRangeEltype} = UnitRange{Int} +Base.eltype(::Type{<:Search{F,Q}}) where {F,Q<:HasRangeEltype} = UnitRange{Int} Base.eltype(::Type{<:Search}) = Int Base.IteratorSize(::Type{<:Search}) = Base.SizeUnknown()