Skip to content

Commit

Permalink
Backport the Iterators module (#296)
Browse files Browse the repository at this point in the history
  • Loading branch information
TotalVerb authored Feb 13, 2017
1 parent ec29bf4 commit a53f102
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ Currently, the `@compat` macro supports the following syntaxes:
* `@compat A{T} = B{T}` or `@compat const A{T} = B{T}` to declare type alias with free
parameters. [#20500]. Use `const A = B` for type alias without free parameters.

## Module Aliases

* In 0.6, some 0.5 iterator functions have been moved to the `Base.Iterators`
module. Code can be written to work on both 0.5 and 0.6 by `import`ing or
`using` the `Compat.Iterators` module instead. ([#18839])

* The `Compat.Iterators` module is also available on 0.4, including the
iterator functions `partition`, `product`, and `flatten`, which were
introduced in Julia 0.5. However, because of a variety of other changes to
the iterator system between 0.4 and 0.5, these functions behave slightly
differently. For example, the `Iterators.product` function on 0.4 does not
return objects with shapes. ([#14596], [#14805], [#15409])

## Type Aliases

* In 0.5, `ASCIIString` and `ByteString` were deprecated, and `UTF8String` was renamed to the (now concrete) type `String`.
Expand Down Expand Up @@ -285,12 +298,15 @@ includes this fix. Find the minimum version from there.
[#13744]: https://github.com/JuliaLang/julia/issues/13744
[#14082]: https://github.com/JuliaLang/julia/issues/14082
[#14338]: https://github.com/JuliaLang/julia/issues/14338
[#14596]: https://github.com/JuliaLang/julia/issues/14596
[#14601]: https://github.com/JuliaLang/julia/issues/14601
[#14660]: https://github.com/JuliaLang/julia/issues/14660
[#14766]: https://github.com/JuliaLang/julia/issues/14766
[#14777]: https://github.com/JuliaLang/julia/issues/14777
[#14805]: https://github.com/JuliaLang/julia/issues/14805
[#15032]: https://github.com/JuliaLang/julia/issues/15032
[#15192]: https://github.com/JuliaLang/julia/issues/15192
[#15409]: https://github.com/JuliaLang/julia/issues/15409
[#15708]: https://github.com/JuliaLang/julia/issues/15708
[#15914]: https://github.com/JuliaLang/julia/issues/15914
[#16154]: https://github.com/JuliaLang/julia/issues/16154
Expand All @@ -307,6 +323,7 @@ includes this fix. Find the minimum version from there.
[#18380]: https://github.com/JuliaLang/julia/issues/18380
[#18484]: https://github.com/JuliaLang/julia/issues/18484
[#18510]: https://github.com/JuliaLang/julia/issues/18510
[#18839]: https://github.com/JuliaLang/julia/issues/18839
[#18977]: https://github.com/JuliaLang/julia/issues/18977
[#19088]: https://github.com/JuliaLang/julia/issues/19088
[#19246]: https://github.com/JuliaLang/julia/issues/19246
Expand All @@ -316,3 +333,4 @@ includes this fix. Find the minimum version from there.
[#20164]: https://github.com/JuliaLang/julia/issues/20164
[#20321]: https://github.com/JuliaLang/julia/issues/20321
[#20414]: https://github.com/JuliaLang/julia/issues/20414
[#20418]: https://github.com/JuliaLang/julia/issues/20418
154 changes: 154 additions & 0 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,160 @@ end # module TypeUtils
# @view, @views, @__dot__
include("arraymacros.jl")

# julia #18839
if VERSION < v"0.6.0-dev.1024"
@eval module Iterators
export countfrom, cycle, drop, enumerate, flatten, product, repeated,
rest, take, zip, partition

import Base: eltype, start, next, done, length, size, ndims
using Base: tuple_type_cons
using Base: countfrom, cycle, drop, enumerate, repeated, rest, take,
zip
using Compat

# julia #14805
if VERSION < v"0.5.0-dev+3256"
immutable Flatten{I}
it::I
end

flatten(itr) = Flatten(itr)

eltype{I}(::Type{Flatten{I}}) = eltype(eltype(I))

function start(f::Flatten)
local inner, s2
s = start(f.it)
d = done(f.it, s)
# this is a simple way to make this function type stable
d && throw(ArgumentError("argument to Flatten must contain at least one iterator"))
while !d
inner, s = next(f.it, s)
s2 = start(inner)
!done(inner, s2) && break
d = done(f.it, s)
end
return s, inner, s2
end

@inline function next(f::Flatten, state)
s, inner, s2 = state
val, s2 = next(inner, s2)
while done(inner, s2) && !done(f.it, s)
inner, s = next(f.it, s)
s2 = start(inner)
end
return val, (s, inner, s2)
end

@inline function done(f::Flatten, state)
s, inner, s2 = state
return done(f.it, s) && done(inner, s2)
end
else
using Base: flatten
end

# julia #14596
if VERSION < v"0.5.0-dev+2305"
# Product -- cartesian product of iterators
@compat abstract type AbstractProdIterator end

immutable Prod2{I1, I2} <: AbstractProdIterator
a::I1
b::I2
end

product(a) = Zip1(a)
product(a, b) = Prod2(a, b)
eltype{I1,I2}(::Type{Prod2{I1,I2}}) = Tuple{eltype(I1), eltype(I2)}
length(p::AbstractProdIterator) = length(p.a)*length(p.b)

function start(p::AbstractProdIterator)
s1, s2 = start(p.a), start(p.b)
s1, s2, Nullable{eltype(p.b)}(), (done(p.a,s1) || done(p.b,s2))
end

@inline function prod_next(p, st)
s1, s2 = st[1], st[2]
v1, s1 = next(p.a, s1)

nv2 = st[3]
if isnull(nv2)
v2, s2 = next(p.b, s2)
else
v2 = nv2.value
end

if done(p.a, s1)
return (v1,v2), (start(p.a), s2, oftype(nv2,nothing), done(p.b,s2))
end
return (v1,v2), (s1, s2, Nullable(v2), false)
end

@inline next(p::Prod2, st) = prod_next(p, st)
@inline done(p::AbstractProdIterator, st) = st[4]

immutable Prod{I1, I2<:AbstractProdIterator} <: AbstractProdIterator
a::I1
b::I2
end

product(a, b, c...) = Prod(a, product(b, c...))
eltype{I1,I2}(::Type{Prod{I1,I2}}) = tuple_type_cons(eltype(I1), eltype(I2))

@inline function next{I1,I2}(p::Prod{I1,I2}, st)
x = prod_next(p, st)
((x[1][1],x[1][2]...), x[2])
end
else
using Base: product
end

# julia #15409
if VERSION < v"0.5.0-dev+3510"
partition{T}(c::T, n::Int) = PartitionIterator{T}(c, n)

type PartitionIterator{T}
c::T
n::Int
end

eltype{T}(::Type{PartitionIterator{T}}) = Vector{eltype(T)}

function length(itr::PartitionIterator)
l = length(itr.c)
return div(l, itr.n) + ((mod(l, itr.n) > 0) ? 1 : 0)
end

start(itr::PartitionIterator) = start(itr.c)

done(itr::PartitionIterator, state) = done(itr.c, state)

function next{T<:Vector}(itr::PartitionIterator{T}, state)
l = state
r = min(state + itr.n-1, length(itr.c))
return sub(itr.c, l:r), r + 1
end

function next(itr::PartitionIterator, state)
v = Vector{eltype(itr.c)}(itr.n)
i = 0
while !done(itr.c, state) && i < itr.n
i += 1
v[i], state = next(itr.c, state)
end
return resize!(v, i), state
end
else
using Base: partition
end
end
else
using Base: Iterators
end

include("to-be-deprecated.jl")

end # module Compat
24 changes: 24 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,30 @@ end
@test isbits(Primitive20418{Int})
@test sizeof(Primitive20418{Int}) == 2

# julia #18839
module Test18839

using Compat
using Compat.Iterators
using Base.Test

@test collect(take(countfrom(2), 3)) == [2, 3, 4]
@test collect(take(cycle(5:8), 9)) == [5:8; 5:8; 5]
@test collect(drop([1, 2, 3], 2)) == [3]
@test collect(enumerate([4, 5, 6])) == [(1,4), (2,5), (3,6)]
@test collect(flatten(Any[1:2, 4:5, Any[-1, 4]])) == [1,2,4,5,-1,4]
@test vec(collect(product([1, 2], [3, 4]))) == [(1,3), (2,3), (1,4), (2,4)]
@test vec(collect(product(1:2, 1:2, 1:2))) == [
(1,1,1), (2,1,1), (1,2,1), (2,2,1),
(1,1,2), (2,1,2), (1,2,2), (2,2,2)]
@test collect(take(repeated(10), 5)) == [10,10,10,10,10]
@test collect(rest(1:10, 5)) == [5,6,7,8,9,10]
@test collect(take([1, 2, 3], 2)) == [1, 2]
@test collect(zip([1,2], [3,4])) == [(1,3), (2,4)]
@test collect(partition(1:5, 2)) == Any[[1,2],[3,4],[5]]

end

# PR #20500
@compat A20500{T<:Integer} = Array{T,20500}
@compat const A20500_2{T<:Union{Int,Float32}} = Pair{T,T}
Expand Down

0 comments on commit a53f102

Please sign in to comment.