From fbca0020c317d2978e7d0ead8b7349302f1af02b Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 14 Sep 2018 12:50:36 +0200 Subject: [PATCH 1/3] move Future.copy! to Base (fix #29173) --- base/abstractarray.jl | 18 +++++++++++++++++ base/abstractdict.jl | 9 ++------- base/abstractset.jl | 2 ++ base/bitset.jl | 8 -------- stdlib/Future/src/Future.jl | 21 ------------------- stdlib/Future/test/runtests.jl | 37 ---------------------------------- test/abstractarray.jl | 16 +++++++++++++++ test/dict.jl | 10 +++++++++ test/sets.jl | 11 ++++++++++ 9 files changed, 59 insertions(+), 73 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index d90e29b7df0a4..ddfc17d89e1ec 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -638,6 +638,24 @@ empty(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}() emptymutable(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}() emptymutable(itr, ::Type{U}) where {U} = Vector{U}() +""" + copy!(dst, src) -> dst + +In-place [`copy`](@ref) of `src` into `dst`, discarding any pre-existing +elements in `dst`. +If `dst` and `src` are of the same type, `dst == src` should hold after +the call. If `dst` and `src` are multidimensional arrays, they must have +equal [`axes`](@ref). +See also [`copyto!`](@ref). +""" +copy!(dst::AbstractVector, src::AbstractVector) = append!(empty!(dst), src) + +function copy!(dst::AbstractArray, src::AbstractArray) + axes(dst) == axes(src) || throw(ArgumentError( + "arrays must have the same axes for copy! (consider using `copyto!`)")) + copyto!(dst, src) +end + ## from general iterable to any array function copyto!(dest::AbstractArray, src) diff --git a/base/abstractdict.jl b/base/abstractdict.jl index 309b8f149d914..2771f6ed31e6d 100644 --- a/base/abstractdict.jl +++ b/base/abstractdict.jl @@ -146,13 +146,8 @@ The default is to return an empty `Dict`. empty(a::AbstractDict) = empty(a, keytype(a), valtype(a)) empty(a::AbstractDict, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`. -function copy(a::AbstractDict) - b = empty(a) - for (k,v) in a - b[k] = v - end - return b -end +copy(a::AbstractDict) = merge!(empty(a), a) +copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) """ merge!(d::AbstractDict, others::AbstractDict...) diff --git a/base/abstractset.jl b/base/abstractset.jl index 100383a126a1d..32aeb0c0f0230 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -3,6 +3,8 @@ eltype(::Type{<:AbstractSet{T}}) where {T} = @isdefined(T) ? T : Any sizehint!(s::AbstractSet, n) = nothing +copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) + """ union(s, itrs...) ∪(s, itrs...) diff --git a/base/bitset.jl b/base/bitset.jl index e575fb7dde7cd..ec7d00ae41b80 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -46,14 +46,6 @@ emptymutable(s::BitSet, ::Type{Int}=Int) = BitSet() copy(s1::BitSet) = copy!(BitSet(), s1) copymutable(s::BitSet) = copy(s) -""" - copy!(dst, src) - -In-place [`copy`](@ref) of `src` into `dst`. After the call to `copy!`, -`dst` must be left equal to `src`, otherwise an error is thrown; this -function appropriately resizes `dst` if necessary. -See also [`copyto!`](@ref). -""" function copy!(dest::BitSet, src::BitSet) resize!(dest.bits, length(src.bits)) copyto!(dest.bits, src.bits) diff --git a/stdlib/Future/src/Future.jl b/stdlib/Future/src/Future.jl index 623b97bc5ba3f..816b8dc5ae640 100644 --- a/stdlib/Future/src/Future.jl +++ b/stdlib/Future/src/Future.jl @@ -6,27 +6,6 @@ module Future using Random -## copy! - -""" - Future.copy!(dst, src) -> dst - -Copy `src` into `dst`. -For collections of the same type, copy the elements of `src` into `dst`, -discarding any pre-existing elements in `dst`. -Usually, `dst == src` holds after the call. -""" -copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) -copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) -copy!(dst::AbstractVector, src::AbstractVector) = append!(empty!(dst), src) - -function copy!(dst::AbstractArray, src::AbstractArray) - axes(dst) == axes(src) || throw(ArgumentError( - "arrays must have the same axes for copy! (consider using `copyto!`)")) - copyto!(dst, src) -end - - ## randjump """ diff --git a/stdlib/Future/test/runtests.jl b/stdlib/Future/test/runtests.jl index 820f4bdd3cedd..6deffe74d891c 100644 --- a/stdlib/Future/test/runtests.jl +++ b/stdlib/Future/test/runtests.jl @@ -2,40 +2,3 @@ using Test using Future -using SparseArrays - -@testset "Future.copy! for AbstractSet" begin - for S = (Set, BitSet) - s = S([1, 2]) - for a = ([1], UInt[1], [3, 4, 5], UInt[3, 4, 5]) - @test s === Future.copy!(s, Set(a)) == S(a) - @test s === Future.copy!(s, BitSet(a)) == S(a) - end - end -end - - -@testset "Future.copy! for AbstractDict" begin - s = Dict(1=>2, 2=>3) - for a = ([3=>4], [0x3=>0x4], [3=>4, 5=>6, 7=>8], Pair{UInt,UInt}[3=>4, 5=>6, 7=>8]) - @test s === Future.copy!(s, Dict(a)) == Dict(a) - if length(a) == 1 # current limitation of Base.ImmutableDict - @test s === Future.copy!(s, Base.ImmutableDict(a[])) == Dict(a[]) - end - end -end - -@testset "Future.copy! for AbstractVector" begin - s = Vector([1, 2]) - for a = ([1], UInt[1], [3, 4, 5], UInt[3, 4, 5]) - @test s === Future.copy!(s, Vector(a)) == Vector(a) - @test s === Future.copy!(s, SparseVector(a)) == Vector(a) - end -end - -@testset "Future.copy! for AbstractArray" begin - @test_throws ArgumentError Future.copy!(zeros(2, 3), zeros(3, 2)) - s = zeros(2, 2) - @test s === Future.copy!(s, fill(1, 2, 2)) == fill(1, 2, 2) - @test s === Future.copy!(s, fill(1.0, 2, 2)) == fill(1.0, 2, 2) -end diff --git a/test/abstractarray.jl b/test/abstractarray.jl index f757191217c7d..b3e19c1f13828 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -912,3 +912,19 @@ end @test hcat(1:2, fill(1, (2,1))) == hcat([1:2;], fill(1, (2,1))) == reshape([1,2,1,1],2,2) @test [(1:3) (4:6); fill(1, (3,2))] == reshape([1,2,3,1,1,1,4,5,6,1,1,1], 6,2) end + +@testset "copy!" begin + @testset "AbstractVector" begin + s = Vector([1, 2]) + for a = ([1], UInt[1], [3, 4, 5], UInt[3, 4, 5]) + @test s === copy!(s, Vector(a)) == Vector(a) + @test s === copy!(s, SparseVector(a)) == Vector(a) + end + end + @testset "AbstractArray" begin + @test_throws ArgumentError copy!(zeros(2, 3), zeros(3, 2)) + s = zeros(2, 2) + @test s === copy!(s, fill(1, 2, 2)) == fill(1, 2, 2) + @test s === copy!(s, fill(1.0, 2, 2)) == fill(1.0, 2, 2) + end +end diff --git a/test/dict.jl b/test/dict.jl index 8476611740ef5..ea3f43414dd34 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -990,3 +990,13 @@ end @test String(take!(buf)) == "Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 3 entries. Keys:\n 5\n ⋮" end + +@testset "copy!" begin + s = Dict(1=>2, 2=>3) + for a = ([3=>4], [0x3=>0x4], [3=>4, 5=>6, 7=>8], Pair{UInt,UInt}[3=>4, 5=>6, 7=>8]) + @test s === copy!(s, Dict(a)) == Dict(a) + if length(a) == 1 # current limitation of Base.ImmutableDict + @test s === copy!(s, Base.ImmutableDict(a[])) == Dict(a[]) + end + end +end diff --git a/test/sets.jl b/test/sets.jl index daddf0bc7bb8b..e9342439f0a2f 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -136,6 +136,17 @@ end @test !in(100,c) @test !in(200,s) end + +@testset "copy!" begin + for S = (Set, BitSet) + s = S([1, 2]) + for a = ([1], UInt[1], [3, 4, 5], UInt[3, 4, 5]) + @test s === copy!(s, Set(a)) == S(a) + @test s === copy!(s, BitSet(a)) == S(a) + end + end +end + @testset "sizehint, empty" begin s = Set([1]) @test isequal(sizehint!(s, 10), Set([1])) From 8bea47e0f6430a397bb7db23e3b3a586d0e59e1d Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 14 Sep 2018 19:16:17 +0200 Subject: [PATCH 2/3] restore Future.copy! --- stdlib/Future/src/Future.jl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/stdlib/Future/src/Future.jl b/stdlib/Future/src/Future.jl index 816b8dc5ae640..26114ee7f387b 100644 --- a/stdlib/Future/src/Future.jl +++ b/stdlib/Future/src/Future.jl @@ -6,6 +6,30 @@ module Future using Random +## copy! + +# This has now been moved to Base (#29178), and should be deprecated in the +# next "deprecation phase". + +""" + Future.copy!(dst, src) -> dst + +Copy `src` into `dst`. +For collections of the same type, copy the elements of `src` into `dst`, +discarding any pre-existing elements in `dst`. +Usually, `dst == src` holds after the call. +""" +copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) +copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) +copy!(dst::AbstractVector, src::AbstractVector) = append!(empty!(dst), src) + +function copy!(dst::AbstractArray, src::AbstractArray) + axes(dst) == axes(src) || throw(ArgumentError( + "arrays must have the same axes for copy! (consider using `copyto!`)")) + copyto!(dst, src) +end + + ## randjump """ From 7b045766640a6345fb895f7553b5bd4a3e7a0b25 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Sun, 16 Sep 2018 11:26:26 +0200 Subject: [PATCH 3/3] call the Base methods (KristofferC) and update docstring --- stdlib/Future/src/Future.jl | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/stdlib/Future/src/Future.jl b/stdlib/Future/src/Future.jl index 26114ee7f387b..c49c0e444b376 100644 --- a/stdlib/Future/src/Future.jl +++ b/stdlib/Future/src/Future.jl @@ -15,19 +15,11 @@ using Random Future.copy!(dst, src) -> dst Copy `src` into `dst`. -For collections of the same type, copy the elements of `src` into `dst`, -discarding any pre-existing elements in `dst`. -Usually, `dst == src` holds after the call. +This function has now been moved into `Base`, consider using `copy!(dst, src)` instead. """ -copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) -copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) -copy!(dst::AbstractVector, src::AbstractVector) = append!(empty!(dst), src) - -function copy!(dst::AbstractArray, src::AbstractArray) - axes(dst) == axes(src) || throw(ArgumentError( - "arrays must have the same axes for copy! (consider using `copyto!`)")) - copyto!(dst, src) -end +copy!(dst::AbstractSet, src::AbstractSet) = Base.copy!(dst, src) +copy!(dst::AbstractDict, src::AbstractDict) = Base.copy!(dst, src) +copy!(dst::AbstractArray, src::AbstractArray) = Base.copy!(dst, src) ## randjump