Skip to content

Commit

Permalink
replace equalto and occursin with curried isequal, ==, and in
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Mar 13, 2018
1 parent 46dcb35 commit 2906bab
Show file tree
Hide file tree
Showing 43 changed files with 314 additions and 308 deletions.
8 changes: 4 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,8 @@ Library improvements

* `diagm` now accepts several diagonal index/vector `Pair`s ([#24047]).

* New function `equalto(x)`, which returns a function that compares its argument to `x`
using `isequal` ([#23812]).
* `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)`
returns a function that compares its argument to `x` using `isequal` ([#23812]).

* `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type.
This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting
Expand Down Expand Up @@ -1022,7 +1022,7 @@ Deprecated or removed
`F.Q` instead of `F[:Q]` ([#25184]).

* `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and
`findlast`/`findprev` respectively, in combination with the new `equalto` and `occursin`
`findlast`/`findprev` respectively, in combination with curried `isequal` and `in`
predicates for some methods ([#24673]

* `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673]).
Expand All @@ -1033,7 +1033,7 @@ Deprecated or removed
`similar(::Associative, ::Pair{K, V})` has been deprecated in favour of
`empty(::Associative, K, V)` ([#24390]).

* `findin(a, b)` has been deprecated in favor of `findall(occursin(b), a)` ([#24673]).
* `findin(a, b)` has been deprecated in favor of `findall(in(b), a)` ([#24673]).

* `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly,
the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor
Expand Down
6 changes: 3 additions & 3 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ get(A::AbstractArray, I::Dims, default) = checkbounds(Bool, A, I...) ? A[I...] :

function get!(X::AbstractVector{T}, A::AbstractVector, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T
# 1d is not linear indexing
ind = findall(occursin(indices1(A)), I)
ind = findall(in(indices1(A)), I)
X[ind] = A[I[ind]]
Xind = indices1(X)
X[first(Xind):first(ind)-1] = default
Expand All @@ -1188,7 +1188,7 @@ function get!(X::AbstractVector{T}, A::AbstractVector, I::Union{AbstractRange,Ab
end
function get!(X::AbstractArray{T}, A::AbstractArray, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T
# Linear indexing
ind = findall(occursin(1:length(A)), I)
ind = findall(in(1:length(A)), I)
X[ind] = A[I[ind]]
X[1:first(ind)-1] = default
X[last(ind)+1:length(X)] = default
Expand Down Expand Up @@ -1361,7 +1361,7 @@ _cs(d, a, b) = (a == b ? a : throw(DimensionMismatch(
"mismatch in dimension $d (expected $a got $b)")))

dims2cat(::Val{n}) where {n} = ntuple(i -> (i == n), Val(n))
dims2cat(dims) = ntuple(occursin(dims), maximum(dims))
dims2cat(dims) = ntuple(in(dims), maximum(dims))

cat(dims, X...) = cat_t(dims, promote_eltypeof(X...), X...)

Expand Down
2 changes: 1 addition & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,7 @@ julia> findfirst(iseven, A)
julia> findfirst(x -> x>10, A) # returns nothing, but not printed in the REPL
julia> findfirst(equalto(4), A)
julia> findfirst(isequal(4), A)
2
julia> A = [1 4; 2 2]
Expand Down
2 changes: 1 addition & 1 deletion base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function parse_input_line(s::String; filename::String="none", depwarn=true)
ccall(:jl_parse_input_line, Any, (Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t),
s, sizeof(s), filename, sizeof(filename))
end
if ex isa Symbol && all(equalto('_'), string(ex))
if ex isa Symbol && all(isequal('_'), string(ex))
# remove with 0.7 deprecation
Meta.lower(Main, ex) # to get possible warning about using _ as an rvalue
end
Expand Down
58 changes: 29 additions & 29 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -712,10 +712,10 @@ end
@deprecate charwidth textwidth

@deprecate find(x::Number) findall(!iszero, x)
@deprecate findnext(A, v, i::Integer) coalesce(findnext(equalto(v), A, i), 0)
@deprecate findfirst(A, v) coalesce(findfirst(equalto(v), A), 0)
@deprecate findprev(A, v, i::Integer) coalesce(findprev(equalto(v), A, i), 0)
@deprecate findlast(A, v) coalesce(findlast(equalto(v), A), 0)
@deprecate findnext(A, v, i::Integer) coalesce(findnext(isequal(v), A, i), 0)
@deprecate findfirst(A, v) coalesce(findfirst(isequal(v), A), 0)
@deprecate findprev(A, v, i::Integer) coalesce(findprev(isequal(v), A, i), 0)
@deprecate findlast(A, v) coalesce(findlast(isequal(v), A), 0)
# to fix ambiguities introduced by deprecations
findnext(pred::Function, A, i::Integer) = invoke(findnext, Tuple{Function, Any, Any}, pred, A, i)
findprev(pred::Function, A, i::Integer) = invoke(findprev, Tuple{Function, Any, Any}, pred, A, i)
Expand Down Expand Up @@ -1198,51 +1198,51 @@ end
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findnext(re, str, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) coalesce(findnext(r, s, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex) coalesce(findfirst(r, s), 0:-1)
@deprecate search(s::AbstractString, c::Char, i::Integer) coalesce(findnext(equalto(c), s, i), 0)
@deprecate search(s::AbstractString, c::Char) coalesce(findfirst(equalto(c), s), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(equalto(b), a, i), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) coalesce(findfirst(equalto(b), a), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(equalto(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}) coalesce(findfirst(equalto(b), unsafe_wrap(Vector{UInt8}, a)), 0)
@deprecate search(a::ByteArray, b::Char, i::Integer) coalesce(findnext(equalto(UInt8(b)), a, i), 0)
@deprecate search(a::ByteArray, b::Char) coalesce(findfirst(equalto(UInt8(b)), a), 0)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findnext(occursin(c), s, i), 0)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findfirst(occursin(c), s), 0)
@deprecate search(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
@deprecate search(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), a, i), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), a), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), unsafe_wrap(Vector{UInt8}, a)), 0)
@deprecate search(a::ByteArray, b::Char, i::Integer) coalesce(findnext(isequal(UInt8(b)), a, i), 0)
@deprecate search(a::ByteArray, b::Char) coalesce(findfirst(isequal(UInt8(b)), a), 0)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findnext(in(c), s, i), 0)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findfirst(in(c), s), 0)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) coalesce(findnext(t, s, i), 0:-1)
@deprecate search(s::AbstractString, t::AbstractString) coalesce(findfirst(t, s), 0:-1)

@deprecate search(buf::IOBuffer, delim::UInt8) coalesce(findfirst(equalto(delim), buf), 0)
@deprecate search(buf::Base.GenericIOBuffer, delim::UInt8) coalesce(findfirst(equalto(delim), buf), 0)
@deprecate search(buf::IOBuffer, delim::UInt8) coalesce(findfirst(isequal(delim), buf), 0)
@deprecate search(buf::Base.GenericIOBuffer, delim::UInt8) coalesce(findfirst(isequal(delim), buf), 0)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findprev(occursin(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findlast(occursin(c), s), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findprev(in(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findlast(in(c), s), 0)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) coalesce(findprev(t, s, i), 0:-1)
@deprecate rsearch(s::AbstractString, t::AbstractString) coalesce(findlast(t, s), 0:-1)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findprev(re, str, idx), 0:-1)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) coalesce(findlast(re, str), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) coalesce(findprev(r, s, idx), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex) coalesce(findlast(r, s), 0:-1)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) coalesce(findprev(equalto(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Char) coalesce(findlast(equalto(c), s), 0)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(equalto(b), a, i), 0)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(equalto(Char(b)), a, i), 0)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) coalesce(findprev(equalto(UInt8(b)), a, i), 0)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(b), a, i), 0)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(Char(b)), a, i), 0)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) coalesce(findprev(isequal(UInt8(b)), a, i), 0)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(coalesce(findfirst(t, s), 0:-1))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findnext(t, s, i), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(coalesce(findlast(t, s), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findprev(t, s, i), 0:-1))

@deprecate searchindex(s::AbstractString, c::Char) coalesce(findfirst(equalto(c), s), 0)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) coalesce(findnext(equalto(c), s, i), 0)
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(equalto(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(equalto(c), s, i), 0)
@deprecate searchindex(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)

@deprecate ismatch(r::Regex, s::AbstractString) contains(s, r)

@deprecate findin(a, b) findall(occursin(b), a)
@deprecate findin(a, b) findall(in(b), a)

@deprecate find findall
@deprecate find(A::AbstractVector) findall(A)
Expand Down
2 changes: 0 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ export
contains,
eachmatch,
endswith,
equalto,
findall,
findfirst,
findlast,
Expand All @@ -459,7 +458,6 @@ export
findmax!,
findnext,
findprev,
occursin,
match,
searchsorted,
searchsortedfirst,
Expand Down
2 changes: 1 addition & 1 deletion base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function argtype_decl(env, n, sig::DataType, i::Int, nargs, isva::Bool) # -> (ar
n = n.args[1] # handle n::T in arg list
end
s = string(n)
i = findfirst(equalto('#'), s)
i = findfirst(isequal('#'), s)
if i !== nothing
s = s[1:i-1]
end
Expand Down
49 changes: 29 additions & 20 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -809,43 +809,52 @@ julia> filter(!isalpha, str)
"""
!(f::Function) = (x...)->!f(x...)

struct EqualTo{T} <: Function
struct Curry2{F,T} <: Function
f::F
x::T

EqualTo(x::T) where {T} = new{T}(x)
Curry2(f::F, x::T) where {F,T} = new{F,T}(f, x)
Curry2(f::Type{F}, x::T) where {F,T} = new{Type{F},T}(f, x)
end

(f::EqualTo)(y) = isequal(f.x, y)
(f::Curry2)(y) = f.f(y, f.x)

"""
equalto(x)
isequal(x)
Create a function that compares its argument to `x` using [`isequal`](@ref); i.e. returns
`y->isequal(x,y)`.
Create a function that compares its argument to `x` using [`isequal`](@ref), i.e.
a function equivalent to `y -> isequal(y, x)`.
The returned function is of type `Base.EqualTo`. This allows dispatching to
specialized methods by using e.g. `f::Base.EqualTo` in a method signature.
The returned function is of type `Base.Curry2{typeof(isequal)}`, which can be
used to implement specialized methods.
"""
const equalto = EqualTo
isequal(x) = Curry2(isequal, x)

struct OccursIn{T} <: Function
x::T
const EqualTo = Curry2{typeof(isequal)}

OccursIn(x::T) where {T} = new{T}(x)
end
"""
==(x)
(f::OccursIn)(y) = y in f.x
Create a function that compares its argument to `x` using [`==`](@ref), i.e.
a function equivalent to `y -> y == x`.
The returned function is of type `Base.Curry2{typeof(==)}`, which can be
used to implement specialized methods.
"""
occursin(x)
==(x) = Curry2(==, x)

Create a function that checks whether its argument is [`in`](@ref) `x`; i.e. returns
`y -> y in x`.
"""
in(x)
Create a function that checks whether its argument is [`in`](@ref) `x`, i.e.
a function equivalent to `y -> y in x`.
The returned function is of type `Base.OccursIn`. This allows dispatching to
specialized methods by using e.g. `f::Base.OccursIn` in a method signature.
The returned function is of type `Base.Curry2{typeof(in)}`, which can be
used to implement specialized methods.
"""
const occursin = OccursIn
in(x) = Curry2(in, x)

const OccursIn = Curry2{typeof(in)}

"""
splat(f)
Expand Down
8 changes: 4 additions & 4 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,16 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String}
end

# find index of ± separating real/imaginary parts (if any)
i₊ = coalesce(findnext(occursin(('+','-')), s, i), 0)
i₊ = coalesce(findnext(in(('+','-')), s, i), 0)
if i₊ == i # leading ± sign
i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0)
i₊ = coalesce(findnext(in(('+','-')), s, i₊+1), 0)
end
if i₊ != 0 && s[i₊-1] in ('e','E') # exponent sign
i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0)
i₊ = coalesce(findnext(in(('+','-')), s, i₊+1), 0)
end

# find trailing im/i/j
iᵢ = coalesce(findprev(occursin(('m','i','j')), s, e), 0)
iᵢ = coalesce(findprev(in(('m','i','j')), s, e), 0)
if iᵢ > 0 && s[iᵢ] == 'm' # im
iᵢ -= 1
if s[iᵢ] != 'i'
Expand Down
2 changes: 1 addition & 1 deletion base/permuteddimsarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ function _copy!(P::PermutedDimsArray{T,N,perm}, src) where {T,N,perm}
copyto!(parent(P), src) # it's not permuted
else
R1 = CartesianIndices(axes(src)[1:d])
d1 = findfirst(equalto(d+1), perm)::Int # first permuted dim of dest
d1 = findfirst(isequal(d+1), perm)::Int # first permuted dim of dest
R2 = CartesianIndices(axes(src)[d+2:d1-1])
R3 = CartesianIndices(axes(src)[d1+1:end])
_permutedims!(P, src, R1, R2, R3, d+1, d1)
Expand Down
6 changes: 3 additions & 3 deletions base/stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,13 @@ end

function wait_readbyte(x::LibuvStream, c::UInt8)
if isopen(x) # fast path
findfirst(equalto(c), x.buffer) !== nothing && return
findfirst(isequal(c), x.buffer) !== nothing && return
else
return
end
preserve_handle(x)
try
while isopen(x) && coalesce(findfirst(equalto(c), x.buffer), 0) <= 0
while isopen(x) && coalesce(findfirst(isequal(c), x.buffer), 0) <= 0
start_reading(x) # ensure we are reading
wait(x.readnotify)
end
Expand Down Expand Up @@ -1074,7 +1074,7 @@ end
show(io::IO, s::BufferStream) = print(io,"BufferStream() bytes waiting:",bytesavailable(s.buffer),", isopen:", s.is_open)

function wait_readbyte(s::BufferStream, c::UInt8)
while isopen(s) && findfirst(equalto(c), s.buffer) === nothing
while isopen(s) && findfirst(isequal(c), s.buffer) === nothing
wait(s.r_c)
end
end
Expand Down
16 changes: 8 additions & 8 deletions base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function findnext(testf::Function, s::AbstractString, i::Integer)
return nothing
end

in(c::AbstractChar, s::AbstractString) = (findfirst(equalto(c),s)!==nothing)
in(c::AbstractChar, s::AbstractString) = (findfirst(isequal(c),s)!==nothing)

function _searchindex(s::Union{AbstractString,ByteArray},
t::Union{AbstractString,AbstractChar,Int8,UInt8},
Expand All @@ -125,7 +125,7 @@ function _searchindex(s::Union{AbstractString,ByteArray},
end
t1, trest = Iterators.peel(t)
while true
i = findnext(equalto(t1),s,i)
i = findnext(isequal(t1),s,i)
if i === nothing return 0 end
ii = nextind(s, i)
a = Iterators.Stateful(trest)
Expand All @@ -135,7 +135,7 @@ function _searchindex(s::Union{AbstractString,ByteArray},
end
end

_searchindex(s::AbstractString, t::AbstractChar, i::Integer) = coalesce(findnext(equalto(t), s, i), 0)
_searchindex(s::AbstractString, t::AbstractChar, i::Integer) = coalesce(findnext(isequal(t), s, i), 0)

function _search_bloom_mask(c)
UInt64(1) << (c & 63)
Expand All @@ -146,7 +146,7 @@ _nthbyte(a::Union{AbstractVector{UInt8},AbstractVector{Int8}}, i) = a[i]

function _searchindex(s::String, t::String, i::Integer)
# Check for fast case of a single byte
lastindex(t) == 1 && return coalesce(findnext(equalto(t[1]), s, i), 0)
lastindex(t) == 1 && return coalesce(findnext(isequal(t[1]), s, i), 0)
_searchindex(unsafe_wrap(Vector{UInt8},s), unsafe_wrap(Vector{UInt8},t), i)
end

Expand All @@ -159,7 +159,7 @@ function _searchindex(s::ByteArray, t::ByteArray, i::Integer)
elseif m == 0
return 0
elseif n == 1
return coalesce(findnext(equalto(_nthbyte(t,1)), s, i), 0)
return coalesce(findnext(isequal(_nthbyte(t,1)), s, i), 0)
end

w = m - n
Expand Down Expand Up @@ -296,7 +296,7 @@ function _rsearchindex(s::AbstractString,
end
t1, trest = Iterators.peel(Iterators.reverse(t))
while true
i = findprev(equalto(t1), s, i)
i = findprev(isequal(t1), s, i)
i === nothing && return 0
ii = prevind(s, i)
a = Iterators.Stateful(trest)
Expand All @@ -314,7 +314,7 @@ end
function _rsearchindex(s::String, t::String, i::Integer)
# Check for fast case of a single byte
if lastindex(t) == 1
return coalesce(findprev(equalto(t[1]), s, i), 0)
return coalesce(findprev(isequal(t[1]), s, i), 0)
elseif lastindex(t) != 0
j = i ncodeunits(s) ? nextind(s, i)-1 : i
return _rsearchindex(unsafe_wrap(Vector{UInt8}, s), unsafe_wrap(Vector{UInt8}, t), j)
Expand All @@ -336,7 +336,7 @@ function _rsearchindex(s::ByteArray, t::ByteArray, k::Integer)
elseif m == 0
return 0
elseif n == 1
return coalesce(findprev(equalto(_nthbyte(t,1)), s, k), 0)
return coalesce(findprev(isequal(_nthbyte(t,1)), s, k), 0)
end

w = m - n
Expand Down
Loading

0 comments on commit 2906bab

Please sign in to comment.