From f40f77c94abdacc7759ea9322d1e29b8ead86438 Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Fri, 26 Jan 2024 18:59:05 +0900 Subject: [PATCH 1/9] extend support for additional array mutation methods empty!, resize!, (append!, push!) and pop! --- src/CircularArrays.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CircularArrays.jl b/src/CircularArrays.jl index e7bfcf3..8320d55 100644 --- a/src/CircularArrays.jl +++ b/src/CircularArrays.jl @@ -129,6 +129,10 @@ Create a `CircularMatrix` of size `size` filled with value `def`. CircularMatrix(def::T, size::NTuple{2, Integer}) where T = CircularMatrix{T}(fill(def, size)) Base.empty(::CircularVector{T}, ::Type{U}=T) where {T,U} = CircularVector{U}(U[]) +Base.empty!(a::CircularVector) = (empty!(parent(a)); a) +# push!, append! can be used by `resize!` method. +Base.resize!(A::CircularVector, nl::Integer) = (resize!(parent(A), nl); A) +Base.pop!(a::CircularVector) = pop!(parent(a)) function Base.deleteat!(a::CircularVector, i::Integer) deleteat!(a.data, mod(i, eachindex(IndexLinear(), a.data))) From 5fd9b6258f1aac750c480fca905aab0a2df5140d Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Fri, 26 Jan 2024 19:01:10 +0900 Subject: [PATCH 2/9] we can use push! method for CircularVector :tada: --- test/runtests.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index baa1632..bab9412 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -96,7 +96,6 @@ end @test prod(v2) == "abcde"^5 - @test_throws MethodError push!(v1, 15) @test empty(v1) isa CircularVector{Int64} @test empty(v1, Float64) isa CircularVector{Float64} From b13e2ac601b3993cd0c3dd2e5c4574e3f1172887 Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Fri, 26 Jan 2024 19:01:56 +0900 Subject: [PATCH 3/9] write tests --- test/runtests.jl | 74 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index bab9412..8097260 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,11 +18,11 @@ end @testset "matrix construction" begin data = zeros(Float64, 2, 2) - ref = CircularArray(data) - @test CircularArray{Float64}(data) == ref + ref = CircularMatrix(data) @test CircularArray{Float64, 2}(data) == ref - @test CircularArray{Float64, 2, Array{Float64, 2}}(data) == ref - @test CircularArray{Float64, 2, Matrix{Float64}}(data) == ref + @test CircularMatrix{Float64}(data) == ref + @test CircularMatrix{Float64, Array{Float64, 2}}(data) == ref + @test CircularMatrix{Float64, Matrix{Float64}}(data) == ref end end @@ -96,10 +96,70 @@ end @test prod(v2) == "abcde"^5 + @testset "empty/empty!" begin + v1 = CircularVector([1,2,3]) + @test empty(v1) isa CircularVector{Int64} + @test empty(v1, Float64) isa CircularVector{Float64} + v1 == CircularVector([]) + # `isempty` can be used to implement `size` method. + @test isempty(empty(v1)) + + v2 = CircularVector("abcde", 5) + @test empty!(v2) isa CircularVector{String} + @test isempty(v2) + end + + @testset "resize!" begin + @test_throws "ArgumentError: new length must be ≥ 0" resize!(CircularVector([]), -2) + v = CircularVector([1,2,3,4,5,6,7]) + resize!(v, 3) + @test length(v) == 3 + + # ensure defining `resize!` induces `push!` and `append!` methods + @testset "push!" begin + v = CircularVector([1,2,3]) + push!(v, 42) + @test v == CircularVector([1,2,3,42]) + push!(v, -9, -99, -999) + @test v == CircularVector([1,2,3,42, -9, -99, -999]) + end + + @testset "append!" begin + v1 = CircularVector([1,2,3]) + append!(v1, [-9, -99, -999]) + @test v1 == CircularVector([1,2,3, -9, -99, -999]) + + v2 = CircularVector([1,2,3]) + append!(v2, CircularVector([-1,-2])) + @test v2 == CircularVector([1,2,3,-1,-2]) + + v3 = CircularVector([1,2,3]) + append!(v3, [4, 5], [6]) + @test v3 == CircularVector([1,2,3,4,5,6]) + + v4 = CircularVector([1,2,3]) + o4 = OffsetVector([-1,-2,-3], -2:0) + append!(v4, o4) + @test v4 == CircularVector([1,2,3,-1,-2,-3]) + + v5 = CircularVector([1,2,3]) + o5 = OffsetVector([-1,-2,-3], -2:0) + append!(v5, o5, -4) + @test v5 == CircularVector([1,2,3,-1,-2,-3,-4]) + end + end - @test empty(v1) isa CircularVector{Int64} - @test empty(v1, Float64) isa CircularVector{Float64} - @test isempty(empty(v1)) + @testset "pop!" begin + v1 = CircularVector([1,2,3,42]) + pop!(v1) == 42 + @test v1 == CircularVector([1,2,3]) + + v2 = CircularVector([1]) + pop!(v2) == 1 + @test v2 == CircularVector([]) + @test isempty(v2) + @test_throws "ArgumentError: array must be non-empty" pop!(v2) + end @testset "deleteat!" begin @test deleteat!(CircularVector([1, 2, 3]), 2) == CircularVector([1, 3]) From 32f65d240a6ebfd06afe163d7c1bda7f251cd9eb Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Wed, 31 Jan 2024 18:51:39 +0900 Subject: [PATCH 4/9] support sizehint! --- src/CircularArrays.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CircularArrays.jl b/src/CircularArrays.jl index 8320d55..6fd8baa 100644 --- a/src/CircularArrays.jl +++ b/src/CircularArrays.jl @@ -133,6 +133,7 @@ Base.empty!(a::CircularVector) = (empty!(parent(a)); a) # push!, append! can be used by `resize!` method. Base.resize!(A::CircularVector, nl::Integer) = (resize!(parent(A), nl); A) Base.pop!(a::CircularVector) = pop!(parent(a)) +Base.sizehint!(a::CircularVector, sz::Integer) = (sizehint!(parent(a), sz); a) function Base.deleteat!(a::CircularVector, i::Integer) deleteat!(a.data, mod(i, eachindex(IndexLinear(), a.data))) From 2c23f6a32b923d074ff3112a6cd2a8f5336415d0 Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Wed, 31 Jan 2024 18:52:03 +0900 Subject: [PATCH 5/9] A -> a --- src/CircularArrays.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CircularArrays.jl b/src/CircularArrays.jl index 6fd8baa..66b7ab7 100644 --- a/src/CircularArrays.jl +++ b/src/CircularArrays.jl @@ -131,7 +131,7 @@ CircularMatrix(def::T, size::NTuple{2, Integer}) where T = CircularMatrix{T}(fil Base.empty(::CircularVector{T}, ::Type{U}=T) where {T,U} = CircularVector{U}(U[]) Base.empty!(a::CircularVector) = (empty!(parent(a)); a) # push!, append! can be used by `resize!` method. -Base.resize!(A::CircularVector, nl::Integer) = (resize!(parent(A), nl); A) +Base.resize!(a::CircularVector, nl::Integer) = (resize!(parent(A), nl); a) Base.pop!(a::CircularVector) = pop!(parent(a)) Base.sizehint!(a::CircularVector, sz::Integer) = (sizehint!(parent(a), sz); a) From fc084162e9bf9526b1ec8ea4440333dde060ef0c Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Wed, 31 Jan 2024 22:28:39 +0900 Subject: [PATCH 6/9] fix --- src/CircularArrays.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CircularArrays.jl b/src/CircularArrays.jl index 66b7ab7..1a935c1 100644 --- a/src/CircularArrays.jl +++ b/src/CircularArrays.jl @@ -131,7 +131,7 @@ CircularMatrix(def::T, size::NTuple{2, Integer}) where T = CircularMatrix{T}(fil Base.empty(::CircularVector{T}, ::Type{U}=T) where {T,U} = CircularVector{U}(U[]) Base.empty!(a::CircularVector) = (empty!(parent(a)); a) # push!, append! can be used by `resize!` method. -Base.resize!(a::CircularVector, nl::Integer) = (resize!(parent(A), nl); a) +Base.resize!(a::CircularVector, nl::Integer) = (resize!(parent(a), nl); a) Base.pop!(a::CircularVector) = pop!(parent(a)) Base.sizehint!(a::CircularVector, sz::Integer) = (sizehint!(parent(a), sz); a) From cfefe9a3db29ebb78c778cbbcd858ca425eb9ec3 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Thu, 18 Apr 2024 15:48:33 +0200 Subject: [PATCH 7/9] Add test for sizehint! --- test/runtests.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 8097260..e3cb3d6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -161,6 +161,13 @@ end @test_throws "ArgumentError: array must be non-empty" pop!(v2) end + @testset "sizehint!" begin + A = CircularVector([1,2,3,4,5,6,7]) + resize!(A, 1) + sizehint!(A, 1) + @test length(A) == 1 + end + @testset "deleteat!" begin @test deleteat!(CircularVector([1, 2, 3]), 2) == CircularVector([1, 3]) @test deleteat!(CircularVector([1, 2, 3]), 5) == CircularVector([1, 3]) From 137bf28b34cbc499019e226b33085fc7faad041d Mon Sep 17 00:00:00 2001 From: Vexatos Date: Thu, 18 Apr 2024 16:22:36 +0200 Subject: [PATCH 8/9] Fix tests on Julia 1.6 --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index e3cb3d6..a5f4095 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -110,7 +110,7 @@ end end @testset "resize!" begin - @test_throws "ArgumentError: new length must be ≥ 0" resize!(CircularVector([]), -2) + @test_throws ArgumentError("new length must be ≥ 0") resize!(CircularVector([]), -2) v = CircularVector([1,2,3,4,5,6,7]) resize!(v, 3) @test length(v) == 3 @@ -158,7 +158,7 @@ end pop!(v2) == 1 @test v2 == CircularVector([]) @test isempty(v2) - @test_throws "ArgumentError: array must be non-empty" pop!(v2) + @test_throws ArgumentError("array must be non-empty") pop!(v2) end @testset "sizehint!" begin From 51dcce53bf69fa5b21ed742d80459ebcda8583e2 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Thu, 18 Apr 2024 18:35:26 +0200 Subject: [PATCH 9/9] Manually implement push! and append! --- src/CircularArrays.jl | 3 ++- test/runtests.jl | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/CircularArrays.jl b/src/CircularArrays.jl index 1a935c1..164b377 100644 --- a/src/CircularArrays.jl +++ b/src/CircularArrays.jl @@ -130,7 +130,8 @@ CircularMatrix(def::T, size::NTuple{2, Integer}) where T = CircularMatrix{T}(fil Base.empty(::CircularVector{T}, ::Type{U}=T) where {T,U} = CircularVector{U}(U[]) Base.empty!(a::CircularVector) = (empty!(parent(a)); a) -# push!, append! can be used by `resize!` method. +Base.push!(a::CircularVector, x...) = (push!(parent(a), x...); a) +Base.append!(a::CircularVector, items) = (append!(parent(a), items); a) Base.resize!(a::CircularVector, nl::Integer) = (resize!(parent(a), nl); a) Base.pop!(a::CircularVector) = pop!(parent(a)) Base.sizehint!(a::CircularVector, sz::Integer) = (sizehint!(parent(a), sz); a) diff --git a/test/runtests.jl b/test/runtests.jl index a5f4095..6aa1552 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -162,10 +162,10 @@ end end @testset "sizehint!" begin - A = CircularVector([1,2,3,4,5,6,7]) - resize!(A, 1) - sizehint!(A, 1) - @test length(A) == 1 + v = CircularVector([1,2,3,4,5,6,7]) + resize!(v, 1) + sizehint!(v, 1) + @test length(v) == 1 end @testset "deleteat!" begin