DataStructures.jl icon indicating copy to clipboard operation
DataStructures.jl copied to clipboard

[bug] Type assert of filter fails for empty `CircularBuffer`

Open kunzaatko opened this issue 3 years ago • 1 comments
trafficstars

Replicate

julia> cb = CircularBuffer(1)
> 0-element CircularBuffer{Any}

julia> filter(s -> s < 3, cb)
ERROR: TypeError: in typeassert, expected AbstractArray{Bool}, got a value of type Vector{Any}
Stacktrace:
 [1] filter(f::var"#25#26", a::CircularBuffer{Any})
   @ Base ./array.jl:2492
 [2] top-level scope
   @ REPL[27]:1

Specifying the eltype does not fix the issue

julia> cb = CircularBuffer{Integer}(1)
> 0-element CircularBuffer{Integer}

julia> filter(s -> s < 3, cb)
ERROR: TypeError: in typeassert, expected AbstractArray{Bool}, got a value of type Vector{Any}
Stacktrace:
 [1] filter(f::var"#39#40", a::CircularBuffer{Integer})
   @ Base ./array.jl:2492
 [2] top-level scope
   @ REPL[37]:1

Desired behaviour

It should behave the same way as with a Vector type.

julia> filter(s -> s < 3, [])
> Any[]

Possible solution

Since filter, returns a Vector type for CircularBuffer there are two solutions that both produce an ideologically different ouput:

  1. Specify the filter method for CircularBuffer to use the method with Array on the underlining buffer and not AbstractArray on the struct,
  2. Overwrite the filter method and make it return a new CircularBuffer.

I would think that the second option is the way to go since it would be easy for the user to use the method outputing Vector on demand.

Can you assign me?

kunzaatko avatar May 08 '22 09:05 kunzaatko

This can be fixed by defining:

Base.IndexStyle(::Type{<:CircularBuffer}) = Base.IndexLinear()

Are there any downsides to this? If now I can prepare a PR. Also fixed by https://github.com/JuliaCollections/DataStructures.jl/pull/641

laborg avatar Oct 03 '23 09:10 laborg