diff --git a/src/unsignediterator.jl b/src/unsignediterator.jl index 61d4ddb..8f9ac7e 100644 --- a/src/unsignediterator.jl +++ b/src/unsignediterator.jl @@ -9,23 +9,15 @@ Base.eltype(::UnsignedIterator) = UInt32 Base.length(u::UnsignedIterator) = count_ones(u.u) Base.size(u::UnsignedIterator) = (count_ones(u.u),) -# @inline function Base.iterate(u::UnsignedIterator, uu = u.u) -# tz = trailing_zeros(uu) % UInt32 -# # tz ≥ 0x00000020 && return nothing -# tz > 0x0000001f && return nothing -# uu ⊻= (0x00000001 << tz) -# tz, uu -# end @inline function Base.iterate(u::UnsignedIterator, (i,uu) = (0x00000000,u.u)) - tz = trailing_zeros(uu) % UInt32 - tz == 0x00000020 && return nothing - i += tz - tz += 0x00000001 - uu >>>= tz - (i, (i+0x00000001,uu)) + tz = trailing_zeros(uu) % UInt32 + tz == oftype(uu, 8*sizeof(uu)) && return nothing + tz += 0x00000001 + i += tz + uu >>>= tz + (i, (i, uu)) end - """ UnsignedIteratorEarlyStop(thread_mask[, num_threads = count_ones(thread_mask)]) @@ -57,6 +49,38 @@ end UnsignedIteratorEarlyStop(u) = UnsignedIteratorEarlyStop(u, count_ones(u) % UInt32) UnsignedIteratorEarlyStop(u, i) = UnsignedIteratorEarlyStop(u, i % UInt32) +@inline _popfirstthread(::Tuple{}, ::Tuple{}, offset) = 0, (), () +@inline function _popfirstthread( + u::Tuple{U,Vararg{U,K}}, a::Tuple{TT,Vararg{TT,K}}, offset +) where {K,T,TT<:UnsignedIterator{T},U<:UnsignedIteratorEarlyStop{T}} + uf = first(u) + af = first(a) + u0 = uf.u + if iszero(u0) + tid0, tupi, tup = _popfirstthread(Base.tail(u), offset + 8sizeof(u0)) + return tid0, (uf, tupi...), (af, tup...) + end + tz = Base.trailing_zeros(u0) + mask = one(u0)<