mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

231 lines
7.7 KiB
Julia

# This file is a part of Julia. License is MIT: https://julialang.org/license
module VersionWeights
importall ....Base.Operators
export VersionWeight
struct HierarchicalValue{T}
v::Vector{T}
rest::T
end
HierarchicalValue{T}(v::Vector{T}) = HierarchicalValue{T}(v, zero(T))
HierarchicalValue(T::Type) = HierarchicalValue(T[])
Base.zero(::Type{HierarchicalValue{T}}) where {T} = HierarchicalValue(T)
Base.typemin(::Type{HierarchicalValue{T}}) where {T} = HierarchicalValue(T[], typemin(T))
for f in (:-, :+)
@eval function Base.$f(a::HierarchicalValue{T}, b::HierarchicalValue{T}) where T
av = a.v
bv = b.v
la = length(a.v)
lb = length(b.v)
l0 = min(la, lb)
l1 = max(la, lb)
ld = la - lb
rv = Vector{T}(l1)
rf = ($f)(a.rest, b.rest)
@inbounds for i = 1:l0
rv[i] = ($f)(av[i], bv[i])
end
@inbounds for i = l0+1:l0+ld
rv[i] = ($f)(av[i], b.rest)
end
@inbounds for i = l0+1:l0-ld
rv[i] = ($f)(a.rest, bv[i])
end
return HierarchicalValue(rv, rf)
end
end
Base.:-(a::HierarchicalValue) = HierarchicalValue(-a.v, -a.rest)
function Base.cmp(a::HierarchicalValue{T}, b::HierarchicalValue{T}) where T
av = a.v
bv = b.v
la = length(a.v)
lb = length(b.v)
l0 = min(la, lb)
l1 = max(la, lb)
ld = la - lb
@inbounds for i = 1:l0
c = cmp(av[i], bv[i]); c != 0 && return c
end
@inbounds for i = l0+1:l0+ld
c = cmp(av[i], b.rest); c != 0 && return c
end
@inbounds for i = l0+1:l0-ld
c = cmp(a.rest, bv[i]); c != 0 && return c
end
return cmp(a.rest, b.rest)
end
Base.isless(a::HierarchicalValue{T}, b::HierarchicalValue{T}) where {T} = cmp(a,b) < 0
Base.:(==)(a::HierarchicalValue{T}, b::HierarchicalValue{T}) where {T} = cmp(a,b) == 0
Base.abs(a::HierarchicalValue{T}) where {T} = HierarchicalValue(T[abs(x) for x in a.v], abs(a.rest))
Base.copy(a::HierarchicalValue{T}) where {T} = HierarchicalValue(T[copy(x) for x in a.v], copy(a.rest))
struct VWPreBuildItem
nonempty::Int
s::HierarchicalValue{Int}
i::Int
end
VWPreBuildItem() = VWPreBuildItem(0, HierarchicalValue(Int), 0)
VWPreBuildItem(i::Int) = VWPreBuildItem(1, HierarchicalValue(Int), i)
VWPreBuildItem(s::String) = VWPreBuildItem(1, HierarchicalValue(Int[s...]), 0)
Base.zero(::Type{VWPreBuildItem}) = VWPreBuildItem()
Base.typemin(::Type{VWPreBuildItem}) = (x=typemin(Int); VWPreBuildItem(x, typemin(HierarchicalValue{Int}), x))
Base.:-(a::VWPreBuildItem, b::VWPreBuildItem) = VWPreBuildItem(a.nonempty-b.nonempty, a.s-b.s, a.i-b.i)
Base.:+(a::VWPreBuildItem, b::VWPreBuildItem) = VWPreBuildItem(a.nonempty+b.nonempty, a.s+b.s, a.i+b.i)
Base.:-(a::VWPreBuildItem) = VWPreBuildItem(-a.nonempty, -a.s, -a.i)
function Base.cmp(a::VWPreBuildItem, b::VWPreBuildItem)
c = cmp(a.nonempty, b.nonempty); c != 0 && return c
c = cmp(a.s, b.s); c != 0 && return c
return cmp(a.i, b.i)
end
Base.isless(a::VWPreBuildItem, b::VWPreBuildItem) = cmp(a,b) < 0
Base.:(==)(a::VWPreBuildItem, b::VWPreBuildItem) = cmp(a,b) == 0
Base.abs(a::VWPreBuildItem) = VWPreBuildItem(abs(a.nonempty), abs(a.s), abs(a.i))
Base.copy(a::VWPreBuildItem) = VWPreBuildItem(a.nonempty, copy(a.s), a.i)
struct VWPreBuild
nonempty::Int
w::HierarchicalValue{VWPreBuildItem}
end
const _vwprebuild_zero = VWPreBuild(0, HierarchicalValue(VWPreBuildItem))
function VWPreBuild(ispre::Bool, desc::Tuple{Vararg{Union{Int,String}}})
isempty(desc) && return _vwprebuild_zero
desc == ("",) && return VWPreBuild(ispre ? -1 : 1, HierarchicalValue(VWPreBuildItem[]))
hv = HierarchicalValue([VWPreBuildItem(item) for item in desc])
return VWPreBuild(ispre ? -1 : 0, hv)
end
VWPreBuild() = _vwprebuild_zero
Base.zero(::Type{VWPreBuild}) = VWPreBuild()
const _vwprebuild_min = VWPreBuild(typemin(Int), typemin(HierarchicalValue{VWPreBuildItem}))
Base.typemin(::Type{VWPreBuild}) = _vwprebuild_min
function Base.:(-)(a::VWPreBuild, b::VWPreBuild)
b === _vwprebuild_zero && return a
a === _vwprebuild_zero && return -b
VWPreBuild(a.nonempty-b.nonempty, a.w-b.w)
end
function Base.:(+)(a::VWPreBuild, b::VWPreBuild)
b === _vwprebuild_zero && return a
a === _vwprebuild_zero && return b
VWPreBuild(a.nonempty+b.nonempty, a.w+b.w)
end
function Base.:(-)(a::VWPreBuild)
a === _vwprebuild_zero && return a
VWPreBuild(-a.nonempty, -a.w)
end
@inline function Base.cmp(a::VWPreBuild, b::VWPreBuild)
a === _vwprebuild_zero && b === _vwprebuild_zero && return 0
c = cmp(a.nonempty, b.nonempty); c != 0 && return c
return cmp(a.w, b.w)
end
Base.isless(a::VWPreBuild, b::VWPreBuild) = cmp(a,b) < 0
Base.:(==)(a::VWPreBuild, b::VWPreBuild) = cmp(a,b) == 0
function Base.abs(a::VWPreBuild)
a === _vwprebuild_zero && return a
VWPreBuild(abs(a.nonempty), abs(a.w))
end
function Base.copy(a::VWPreBuild)
a === _vwprebuild_zero && return a
VWPreBuild(a.nonempty, copy(a.w))
end
function Base.deepcopy_internal(a::VWPreBuild, dict::ObjectIdDict)
haskey(dict, a) && return dict[a]
b = (a === _vwprebuild_zero) ? _vwprebuild_zero : VWPreBuild(a.nonempty, Base.deepcopy_internal(a.w, dict))
dict[a] = b
return b
end
# The numeric type used to determine how the different
# versions of a package should be weighed
struct VersionWeight
major::Int
minor::Int
patch::Int
prerelease::VWPreBuild
build::VWPreBuild
end
VersionWeight(major::Int, minor::Int, patch::Int, prerelease::VWPreBuild) = VersionWeight(major, minor, patch, prerelease, zero(VWPreBuild))
VersionWeight(major::Int, minor::Int, patch::Int) = VersionWeight(major, minor, patch, zero(VWPreBuild))
VersionWeight(major::Int, minor::Int) = VersionWeight(major, minor, 0)
VersionWeight(major::Int) = VersionWeight(major, 0)
VersionWeight() = VersionWeight(0)
VersionWeight(vn::VersionNumber) =
VersionWeight(vn.major, vn.minor, vn.patch,
VWPreBuild(true, vn.prerelease), VWPreBuild(false, vn.build))
Base.zero(::Type{VersionWeight}) = VersionWeight()
Base.typemin(::Type{VersionWeight}) = (x=typemin(Int); y=typemin(VWPreBuild); VersionWeight(x, x, x, y, y))
Base.:(-)(a::VersionWeight, b::VersionWeight) =
VersionWeight(a.major-b.major, a.minor-b.minor, a.patch-b.patch,
a.prerelease-b.prerelease, a.build-b.build)
Base.:(+)(a::VersionWeight, b::VersionWeight) =
VersionWeight(a.major+b.major, a.minor+b.minor, a.patch+b.patch,
a.prerelease+b.prerelease, a.build+b.build)
Base.:(-)(a::VersionWeight) =
VersionWeight(-a.major, -a.minor, -a.patch,
-a.prerelease, -a.build)
function Base.cmp(a::VersionWeight, b::VersionWeight)
c = cmp(a.major, b.major); c != 0 && return c
c = cmp(a.minor, b.minor); c != 0 && return c
c = cmp(a.patch, b.patch); c != 0 && return c
c = cmp(a.prerelease, b.prerelease); c != 0 && return c
return cmp(a.build, b.build)
end
Base.isless(a::VersionWeight, b::VersionWeight) = cmp(a,b) < 0
Base.:(==)(a::VersionWeight, b::VersionWeight) = cmp(a,b) == 0
Base.abs(a::VersionWeight) =
VersionWeight(abs(a.major), abs(a.minor), abs(a.patch),
abs(a.prerelease), abs(a.build))
Base.copy(a::VersionWeight) =
VersionWeight(a.major, a.minor, a.patch,
copy(a.prerelease), copy(a.build))
# This isn't nice, but it's for debugging only anyway
function Base.show(io::IO, a::VersionWeight)
print(io, "(", a.major)
a == VersionWeight(a.major) && @goto done
print(io, ".", a.minor)
a == VersionWeight(a.major, a.minor) && @goto done
print(io, ".", a.patch)
a.prerelease _vwprebuild_zero && print(io, "-", a.prerelease)
a.build _vwprebuild_zero && print(io, "+", a.build)
@label done
print(io, ")")
end
end