From b0a55b864106e6e82724e67de1b68d5db010ea4b Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 13 Jul 2020 05:22:34 -0500 Subject: [PATCH] More improvements to inference in IO and unique! (#36449) --- base/io.jl | 52 +++++++++++++++++++++++++------------------------- base/libc.jl | 2 +- base/set.jl | 28 +++++++++------------------ base/traits.jl | 2 ++ 4 files changed, 38 insertions(+), 46 deletions(-) diff --git a/base/io.jl b/base/io.jl index df7f79cf604c6..05dd2198d68e9 100644 --- a/base/io.jl +++ b/base/io.jl @@ -357,35 +357,35 @@ end function pipe_reader end function pipe_writer end -write(io::AbstractPipe, byte::UInt8) = write(pipe_writer(io), byte) -unsafe_write(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_write(pipe_writer(io), p, nb) -buffer_writes(io::AbstractPipe, args...) = buffer_writes(pipe_writer(io), args...) -flush(io::AbstractPipe) = flush(pipe_writer(io)) - -read(io::AbstractPipe, byte::Type{UInt8}) = read(pipe_reader(io), byte) -unsafe_read(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_read(pipe_reader(io), p, nb) -read(io::AbstractPipe) = read(pipe_reader(io)) -readuntil(io::AbstractPipe, arg::UInt8; kw...) = readuntil(pipe_reader(io), arg; kw...) -readuntil(io::AbstractPipe, arg::AbstractChar; kw...) = readuntil(pipe_reader(io), arg; kw...) -readuntil(io::AbstractPipe, arg::AbstractString; kw...) = readuntil(pipe_reader(io), arg; kw...) -readuntil(io::AbstractPipe, arg::AbstractVector; kw...) = readuntil(pipe_reader(io), arg; kw...) -readuntil_vector!(io::AbstractPipe, target::AbstractVector, keep::Bool, out) = readuntil_vector!(pipe_reader(io), target, keep, out) -readbytes!(io::AbstractPipe, target::AbstractVector{UInt8}, n=length(target)) = readbytes!(pipe_reader(io), target, n) +write(io::AbstractPipe, byte::UInt8) = write(pipe_writer(io)::IO, byte) +unsafe_write(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_write(pipe_writer(io)::IO, p, nb) +buffer_writes(io::AbstractPipe, args...) = buffer_writes(pipe_writer(io)::IO, args...) +flush(io::AbstractPipe) = flush(pipe_writer(io)::IO) + +read(io::AbstractPipe, byte::Type{UInt8}) = read(pipe_reader(io)::IO, byte) +unsafe_read(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_read(pipe_reader(io)::IO, p, nb) +read(io::AbstractPipe) = read(pipe_reader(io)::IO) +readuntil(io::AbstractPipe, arg::UInt8; kw...) = readuntil(pipe_reader(io)::IO, arg; kw...) +readuntil(io::AbstractPipe, arg::AbstractChar; kw...) = readuntil(pipe_reader(io)::IO, arg; kw...) +readuntil(io::AbstractPipe, arg::AbstractString; kw...) = readuntil(pipe_reader(io)::IO, arg; kw...) +readuntil(io::AbstractPipe, arg::AbstractVector; kw...) = readuntil(pipe_reader(io)::IO, arg; kw...) +readuntil_vector!(io::AbstractPipe, target::AbstractVector, keep::Bool, out) = readuntil_vector!(pipe_reader(io)::IO, target, keep, out) +readbytes!(io::AbstractPipe, target::AbstractVector{UInt8}, n=length(target)) = readbytes!(pipe_reader(io)::IO, target, n) for f in ( # peek/mark interface :mark, :unmark, :reset, :ismarked, # Simple reader functions :readavailable, :isreadable) - @eval $(f)(io::AbstractPipe) = $(f)(pipe_reader(io)) + @eval $(f)(io::AbstractPipe) = $(f)(pipe_reader(io)::IO) end -peek(io::AbstractPipe, ::Type{T}) where {T} = peek(pipe_reader(io), T) +peek(io::AbstractPipe, ::Type{T}) where {T} = peek(pipe_reader(io)::IO, T) -iswritable(io::AbstractPipe) = iswritable(pipe_writer(io)) -isopen(io::AbstractPipe) = isopen(pipe_writer(io)) || isopen(pipe_reader(io)) -close(io::AbstractPipe) = (close(pipe_writer(io)); close(pipe_reader(io))) -wait_readnb(io::AbstractPipe, nb::Int) = wait_readnb(pipe_reader(io), nb) -wait_close(io::AbstractPipe) = (wait_close(pipe_writer(io)); wait_close(pipe_reader(io))) +iswritable(io::AbstractPipe) = iswritable(pipe_writer(io)::IO) +isopen(io::AbstractPipe) = isopen(pipe_writer(io)::IO) || isopen(pipe_reader(io)::IO) +close(io::AbstractPipe) = (close(pipe_writer(io)::IO); close(pipe_reader(io)::IO)) +wait_readnb(io::AbstractPipe, nb::Int) = wait_readnb(pipe_reader(io)::IO, nb) +wait_close(io::AbstractPipe) = (wait_close(pipe_writer(io)::IO); wait_close(pipe_reader(io)::IO)) """ bytesavailable(io) @@ -400,7 +400,7 @@ julia> bytesavailable(io) 34 ``` """ -bytesavailable(io::AbstractPipe) = bytesavailable(pipe_reader(io)) +bytesavailable(io::AbstractPipe) = bytesavailable(pipe_reader(io)::IO) """ eof(stream) -> Bool @@ -412,7 +412,7 @@ it is always safe to read one byte after seeing `eof` return `false`. `eof` will is closed. """ eof(io::AbstractPipe) = eof(pipe_reader(io)::IO)::Bool -reseteof(io::AbstractPipe) = reseteof(pipe_reader(io)) +reseteof(io::AbstractPipe) = reseteof(pipe_reader(io)::IO) # Exception-safe wrappers (io = open(); try f(io) finally close(io)) @@ -503,8 +503,8 @@ function readline(filename::AbstractString; keep::Bool=false) end end -function readline(s::IO=stdin; keep::Bool=false)::String - line = readuntil(s, 0x0a, keep=true) +function readline(s::IO=stdin; keep::Bool=false) + line = readuntil(s, 0x0a, keep=true)::Vector{UInt8} i = length(line) if keep || i == 0 || line[i] != 0x0a return String(line) @@ -766,7 +766,7 @@ end # readuntil_string is useful below since it has # an optimized method for s::IOStream -readuntil_string(s::IO, delim::UInt8, keep::Bool) = String(readuntil(s, delim, keep=keep)) +readuntil_string(s::IO, delim::UInt8, keep::Bool) = String(readuntil(s, delim, keep=keep))::String function readuntil(s::IO, delim::AbstractChar; keep::Bool=false) if delim ≤ '\x7f' diff --git a/base/libc.jl b/base/libc.jl index 2f7aa2c3abe0c..547561ac964ba 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -5,7 +5,7 @@ module Libc Interface to libc, the C standard library. """ Libc -import Base: transcode, windowserror +import Base: transcode, windowserror, show import Core.Intrinsics: bitcast export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, calloc, realloc, diff --git a/base/set.jl b/base/set.jl index 32eef31f9cf51..afc118edb2526 100644 --- a/base/set.jl +++ b/base/set.jl @@ -289,7 +289,7 @@ function _unique!(f, A::AbstractVector, seen::Set, current::Integer, i::Integer) end i += 1 end - return resize!(A, current - firstindex(A) + 1) + return resize!(A, current - firstindex(A) + 1)::typeof(A) end @@ -315,7 +315,7 @@ function _groupedunique!(A::AbstractVector) it = iterate(idxs, it[2]) end end - resize!(A, count) + resize!(A, count)::typeof(A) end """ @@ -352,24 +352,14 @@ julia> unique!(B) 42 ``` """ -function unique!(A::Union{AbstractVector{<:Real}, AbstractVector{<:AbstractString}, - AbstractVector{<:Symbol}}) - if isempty(A) - return A - elseif issorted(A) || issorted(A, rev=true) - return _groupedunique!(A) - else - return _unique!(A) - end -end -# issorted fails for some element types, so the method above has to be restricted to -# elements with isless/< defined. -function unique!(A) - if isempty(A) - return A - else - return _unique!(A) +function unique!(itr) + if isa(itr, AbstractVector) + if OrderStyle(eltype(itr)) === Ordered() + (issorted(itr) || issorted(itr, rev=true)) && return _groupedunique!(itr) + end end + isempty(itr) && return itr + return _unique!(itr) end """ diff --git a/base/traits.jl b/base/traits.jl index 3c6a8019483b7..b7239230686c8 100644 --- a/base/traits.jl +++ b/base/traits.jl @@ -8,6 +8,8 @@ struct Unordered <: OrderStyle end OrderStyle(instance) = OrderStyle(typeof(instance)) OrderStyle(::Type{<:Real}) = Ordered() +OrderStyle(::Type{<:AbstractString}) = Ordered() +OrderStyle(::Type{Symbol}) = Ordered() OrderStyle(::Type{<:Any}) = Unordered() # trait for objects that support arithmetic