struct UnsignedIterator{U}
    u::U
end

Base.IteratorSize(::Type{<:UnsignedIterator}) = Base.HasShape{1}()
Base.IteratorEltype(::Type{<:UnsignedIterator}) = Base.HasEltype()

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))
end


"""
    UnsignedIteratorEarlyStop(thread_mask[, num_threads = count_ones(thread_mask)])

Iterator, returning `(i,t) = Tuple{UInt32,UInt32}`, where `i` iterates from `1,2,...,num_threads`, and `t` gives the threadids to call `ThreadingUtilities.taskpointer` with.


Unfortunately, codegen is suboptimal when used in the ergonomic `for (i,tid) ∈ thread_iterator` fashion. If you want to microoptimize,
You'd get better performance from a pattern like:
```julia
function sumk(u,l = count_ones(u) % UInt32)
    uu = ServiceSolicitation.UnsignedIteratorEarlyStop(u,l)
    s = zero(UInt32); state = ServiceSolicitation.initial_state(uu)
    while true
        iter = iterate(uu, state)
        iter === nothing && break
        (i,t),state = iter
        s += t
    end
    s
end
```

This iterator will iterate at least once; it's important to check and exit early with a single threaded version.
"""
struct UnsignedIteratorEarlyStop{U}
    u::U
    i::UInt32
end
UnsignedIteratorEarlyStop(u) = UnsignedIteratorEarlyStop(u, count_ones(u) % UInt32)
UnsignedIteratorEarlyStop(u, i) = UnsignedIteratorEarlyStop(u, i % UInt32)

mask(u::UnsignedIteratorEarlyStop) = getfield(u, :u)
Base.IteratorSize(::Type{<:UnsignedIteratorEarlyStop}) = Base.HasShape{1}()
Base.IteratorEltype(::Type{<:UnsignedIteratorEarlyStop}) = Base.HasEltype()

Base.eltype(::UnsignedIteratorEarlyStop) = Tuple{UInt32,UInt32}
Base.length(u::UnsignedIteratorEarlyStop) = getfield(u, :i)
Base.size(u::UnsignedIteratorEarlyStop) = (getfield(u, :i),)

@inline function initial_state(u::UnsignedIteratorEarlyStop)
  # LLVM should figure this out if you check?
  assume(0x00000000 ≠ u.i)
  (0x00000000,u.u)
end
@inline function iter(i, uu)
  assume(uu ≠ zero(uu))
  tz = trailing_zeros(uu) % UInt32
  tz += 0x00000001
  i += tz
  uu >>>= tz
  i, uu
end
@inline function Base.iterate(u::UnsignedIteratorEarlyStop, ((i,uu),j) = (initial_state(u),0x00000000))
  # assume(u.i ≤ 0x00000020)
  # assume(j ≤ count_ones(uu))
  # iszero(j) && return nothing
  j == u.i && return nothing
  j += 0x00000001
  i, uu = iter(i, uu)
  ((j, i), ((i, uu), j))
end
function Base.show(io::IO, u::UnsignedIteratorEarlyStop)
    l = length(u)
    s = Vector{Int}(undef, l)
    if l > 0
        s .= last.(u)
    end
    print("Thread ($l) Iterator: U", s)
end

# @inline function Base.iterate(u::UnsignedIteratorEarlyStop, (i,uu) = (0xffffffff,u.u))
#     tz = trailing_zeros(uu) % UInt32
#     tz == 0x00000020 && return nothing
#     tz += 0x00000001
#     i += tz
#     uu >>>= tz
#     (i, (i,uu))
# end
