@@ -284,9 +284,9 @@ julia> first([1; 2; 3; 4])
284284``` 
285285""" 
286286function  first (itr)
287-     state  =  start (itr)
288-     done (itr, state)  &&  throw (ArgumentError (" collection must be non-empty" 
289-     next (itr, state) [1 ]
287+     x  =  iterate (itr)
288+     x  ===   nothing  &&  throw (ArgumentError (" collection must be non-empty" 
289+     x [1 ]
290290end 
291291
292292""" 
@@ -635,10 +635,12 @@ emptymutable(itr, ::Type{U}) where {U} = Vector{U}()
635635
636636function  copyto! (dest:: AbstractArray , src)
637637    destiter =  eachindex (dest)
638-     state  =  start (destiter)
638+     y  =  iterate (destiter)
639639    for  x in  src
640-         i, state =  next (destiter, state)
641-         dest[i] =  x
640+         y ===  nothing  && 
641+             throw (ArgumentError (string (" source has fewer elements than required" 
642+         dest[y[1 ]] =  x
643+         y =  iterate (destiter, y[2 ])
642644    end 
643645    return  dest
644646end 
@@ -657,25 +659,24 @@ function copyto!(dest::AbstractArray, dstart::Integer, src, sstart::Integer)
657659    if  (sstart <  1 )
658660        throw (ArgumentError (string (" source start offset (" " ) is < 1" 
659661    end 
660-     st  =  start (src)
662+     y  =  iterate (src)
661663    for  j =  1 : (sstart- 1 )
662-         if  done (src, st) 
664+         if  y  ===   nothing 
663665            throw (ArgumentError (string (" source has fewer elements than required, " 
664666                                       " expected at least " " , got " - 1 )))
665667        end 
666-         _, st  =   next (src, st )
668+         y  =   iterate (src, y[ 2 ] )
667669    end 
668-     dn =  done (src, st)
669-     if  dn
670+     if  y ===  nothing 
670671        throw (ArgumentError (string (" source has fewer elements than required, " 
671672                                      " expected at least " " , got " - 1 )))
672673    end 
673674    i =  Int (dstart)
674-     while  ! dn 
675-         val, st =  next (src, st) 
675+     while  y  !=   nothing 
676+         val, st =  y 
676677        dest[i] =  val
677678        i +=  1 
678-         dn  =  done (src, st)
679+         y  =  iterate (src, st)
679680    end 
680681    return  dest
681682end 
@@ -690,18 +691,19 @@ function copyto!(dest::AbstractArray, dstart::Integer, src, sstart::Integer, n::
690691        sstart <  1  &&  throw (ArgumentError (string (" source start offset (" " ) is < 1" 
691692        throw (BoundsError (dest, dstart: dmax))
692693    end 
693-     st  =  start (src)
694+     y  =  iterate (src)
694695    for  j =  1 : (sstart- 1 )
695-         if  done (src, st) 
696+         if  y  ===   nothing 
696697            throw (ArgumentError (string (" source has fewer elements than required, " 
697698                                       " expected at least " " , got " - 1 )))
698699        end 
699-         _, st  =   next (src, st )
700+         y  =   iterate (src, y[ 2 ] )
700701    end 
701702    i =  Int (dstart)
702-     while  i <=  dmax &&  ! done (src, st) 
703-         val, st =  next (src, st) 
703+     while  i <=  dmax &&  y  != =   nothing 
704+         val, st =  y 
704705        @inbounds  dest[i] =  val
706+         y =  iterate (src, st)
705707        i +=  1 
706708    end 
707709    i <=  dmax &&  throw (BoundsError (dest, i))
@@ -823,9 +825,11 @@ zero(x::AbstractArray{T}) where {T} = fill!(similar(x), zero(T))
823825#  While the definitions for IndexLinear are all simple enough to inline on their
824826#  own, IndexCartesian's CartesianIndices is more complicated and requires explicit
825827#  inlining.
826- start (A:: AbstractArray ) =  (@_inline_meta ; itr =  eachindex (A); (itr, start (itr)))
827- next (A:: AbstractArray , i) =  (@_propagate_inbounds_meta ; (idx, s) =  next (i[1 ], i[2 ]); (A[idx], (i[1 ], s)))
828- done (A:: AbstractArray , i) =  (@_propagate_inbounds_meta ; done (i[1 ], i[2 ]))
828+ function  iterate (A:: AbstractArray , state= (eachindex (A),))
829+     y =  iterate (state... )
830+     y ===  nothing  &&  return  nothing 
831+     A[y[1 ]], (state[1 ], tail (y)... )
832+ end 
829833
830834isempty (a:: AbstractArray ) =  (_length (a) ==  0 )
831835
@@ -2042,12 +2046,17 @@ function hash(a::AbstractArray{T}, h::UInt) where T
20422046    h +=  hashaa_seed
20432047    h +=  hash (size (a))
20442048
2045-     state =  start (a)
2046-     done (a, state) &&  return  h
2047-     x1, state =  next (a, state)
2048-     done (a, state) &&  return  hash (x1, h)
2049-     x2, state =  next (a, state)
2050-     done (a, state) &&  return  hash (x2, hash (x1, h))
2049+     y1 =  iterate (a)
2050+     y1 ===  nothing  &&  return  h
2051+     y2 =  iterate (a, y1[2 ])
2052+     y2 ===  nothing  &&  return  hash (y1[1 ], h)
2053+     y =  iterate (a, y2[2 ])
2054+     y ===  nothing  &&  return  hash (y2[1 ], hash (y1[1 ], h))
2055+     x1, x2 =  y1[1 ], y2[1 ]
2056+ 
2057+     #  For the rest of the function, we keep three elements worth of state,
2058+     #  x1, x2, y[1], with `y` potentially being `nothing` if there's only
2059+     #  two elements remaining
20512060
20522061    #  Check whether the array is equal to a range, and hash the elements
20532062    #  at the beginning of the array as such as long as they match this assumption
@@ -2056,6 +2065,10 @@ function hash(a::AbstractArray{T}, h::UInt) where T
20562065    if  isa (a, AbstractVector) &&  applicable (- , x2, x1)
20572066        n =  1 
20582067        local  step, laststep, laststate
2068+ 
2069+         h =  hash (x1, h)
2070+         h +=  hashr_seed
2071+ 
20592072        while  true 
20602073            #  If overflow happens with entries of the same type, a cannot be equal
20612074            #  to a range with more than two elements because more extreme values
@@ -2077,47 +2090,48 @@ function hash(a::AbstractArray{T}, h::UInt) where T
20772090            end 
20782091            n >  1  &&  ! isequal (step, laststep) &&  break 
20792092            n +=  1 
2080-             x1 =  x2
20812093            laststep =  step
2082-             laststate =  state
2083-             done (a, state) &&  break 
2084-             x2, state =  next (a, state)
2094+             if  y ===  nothing 
2095+                 #  The array matches a range exactly
2096+                 return  hash (x2, hash (n, h))
2097+             end 
2098+             x1, x2 =  x2, y[1 ]
2099+             y =  iterate (a, y[2 ])
20852100        end 
20862101
2087-         h =  hash (first (a), h)
2088-         h +=  hashr_seed
20892102        #  Always hash at least the two first elements as a range (even in case of overflow)
20902103        if  n <  2 
20912104            h =  hash (2 , h)
2092-             h =  hash (x2 , h)
2093-             done (a, state)  &&   return  h 
2094-             x1  =  x2
2095-             x2, state  =   next (a, state )
2105+             h =  hash (y2[ 1 ] , h)
2106+             @assert  y  != =   nothing 
2107+             x1, x2  =  x2, y[ 1 ] 
2108+             y  =   iterate (a, y[ 2 ] )
20962109        else 
20972110            h =  hash (n, h)
20982111            h =  hash (x1, h)
2099-             done (a, laststate) &&  return  h
21002112        end 
21012113    end 
21022114
2103-     #  Hash elements which do not correspond to a range (if any) 
2115+     #  Hash elements which do not correspond to a range
21042116    while  true 
21052117        if  isequal (x2, x1)
21062118            #  For repeated elements, use run length encoding
21072119            #  This allows efficient hashing of sparse arrays
21082120            runlength =  2 
2109-             while  ! done (a, state)
2110-                 x2, state =  next (a, state)
2121+             while  y != =  nothing 
2122+                 #  No need to update x1 (it's isequal x2)
2123+                 x2 =  y[1 ]
2124+                 y =  iterate (a, y[2 ])
21112125                isequal (x1, x2) ||  break 
21122126                runlength +=  1 
21132127            end 
21142128            h +=  hashrle_seed
21152129            h =  hash (runlength, h)
21162130        end 
21172131        h =  hash (x1, h)
2118-         done (a, state)  &&  break 
2119-         x1  =  x2
2120-         x2, state  =   next (a, state )
2132+         y  ===   nothing  &&  break 
2133+         x1, x2  =  x2, y[ 1 ] 
2134+         y  =   iterate (a, y[ 2 ] )
21212135    end 
21222136    ! isequal (x2, x1) &&  (h =  hash (x2, h))
21232137    return  h
0 commit comments