text:
using DocumentFormat: format
using Test

@testset "All" begin
    @testset "basic" begin
        @test format("a") == "a"
    end
    @testset "tuples" begin
        @test format("a,b") == "a, b"
        @test format("a ,b") == "a, b"
        @test format("a ,b") == "a, b"
        @test format("a ,b") == "a, b"
        @test format("a , b") == "a, b"
        @test format("(a,b)") == "(a, b)"
        @test format("(a ,b)") == "(a, b)"
        @test format("( a, b)") == "(a, b)"
        @test format("(a, b )") == "(a, b)"
        @test format("(a, b ,)") == "(a, b,)"
        @test format("π,汉") == "π, 汉"
        @test format("π ,汉") == "π, 汉"
        @test format("π ,汉") == "π, 汉"
        @test format("π ,汉") == "π, 汉"
        @test format("π , 汉") == "π, 汉"
        @test format("(π,汉)") == "(π, 汉)"
        @test format("(π ,汉)") == "(π, 汉)"
        @test format("( π, 汉)") == "(π, 汉)"
        @test format("(π, 汉 )") == "(π, 汉)"
        @test format("(π, 汉 )") == "(π, 汉)"
    end
    @testset "curly" begin
        @test format("X{a,b}") == "X{a,b}"
        @test format("X{ a,b}") == "X{a,b}"
        @test format("X{a ,b}") == "X{a,b}"
        @test format("X{a, b}") == "X{a,b}"
        @test format("X{a,b }") == "X{a,b}"
        @test format("X{a,b }") == "X{a,b}"
        @test format("X{π,汉}") == "X{π,汉}"
        @test format("X{ π,汉}") == "X{π,汉}"
        @test format("X{π ,汉}") == "X{π,汉}"
        @test format("X{π, 汉}") == "X{π,汉}"
        @test format("X{π,汉 }") == "X{π,汉}"
        @test format("X{π,汉 }") == "X{π,汉}"
    end
# @testset "unary ops" begin
#     @test format("! x") == "!x"
# end
    @testset "binary ops" begin
        @test format("a+b*c") == "a + b * c"
        @test format("a +b*c") == "a + b * c"
        @test format("a+ b*c") == "a + b * c"
        @test format("a+b *c") == "a + b * c"
        @test format("a+b* c") == "a + b * c"
        @test format("a+b*c ") == "a + b * c "
        @test format("a:b") == "a:b"
        @test format("a : b") == "a:b"
        @test format("a: b") == "a:b"
        @test format("a :b") == "a:b"
        @test format("a:b:c") == "a:b:c"
        @test format("a :b:c") == "a:b:c"
        @test format("a: b:c") == "a:b:c"
        @test format("a:b :c") == "a:b:c"
        @test format("a:b: c") == "a:b:c"
        @test format("a:b:c ") == "a:b:c "
        @test format("a::b:: c") == "a::b::c"
        @test format("a :: b::c") == "a::b::c"
        @test format("π+σ*汉") == "π + σ * 汉"
        @test format("π +σ*汉") == "π + σ * 汉"
        @test format("π+ σ*汉") == "π + σ * 汉"
        @test format("π+σ *汉") == "π + σ * 汉"
        @test format("π+σ* 汉") == "π + σ * 汉"
        @test format("π+σ*汉 ") == "π + σ * 汉 "
        @test format("π:汉") == "π:汉"
        @test format("π : 汉") == "π:汉"
        @test format("π: 汉") == "π:汉"
        @test format("π :汉") == "π:汉"
        @test format("π:σ:汉") == "π:σ:汉"
        @test format("π :σ:汉") == "π:σ:汉"
        @test format("π: σ:汉") == "π:σ:汉"
        @test format("π:σ :汉") == "π:σ:汉"
        @test format("π:σ: 汉") == "π:σ:汉"
        @test format("π:σ:汉 ") == "π:σ:汉 "
        @test format("π::σ:: 汉") == "π::σ::汉"
        @test format("π :: σ::汉") == "π::σ::汉"
        @test format("-π/ 2") == "-π / 2"
    end

    @testset "op chain" begin
        @test format("a+b+c+d") == "a + b + c + d"
        @test format("π+σ+汉+a汉π") == "π + σ + 汉 + a汉π"
    end

    @testset "comparison chain" begin
        @test format("a<b==c≥d") == "a < b == c ≥ d"
        @test format("π<σ==汉≥a汉π") == "π < σ == 汉 ≥ a汉π"
    end

    @testset "colon op" begin
        @test format("a:b:c") == "a:b:c"
        @test format("a:b:c") == "a:b:c"
        @test format("a:b:c") == "a:b:c"
        @test format("a:b:c") == "a:b:c"
        @test format("a:b:c") == "a:b:c"
        @test format("a:b:c") == "a:b:c"
        @test format("π:σ:汉") == "π:σ:汉"
    end

# @testset "func call" begin
#     @test format("func(a, b, c)") == "func(a, b, c)"
#     @test format("func(a,b,c)") == "func(a, b, c)"
#     @test format("func(a,b,c,)") == "func(a, b, c,)"
#     @test format("func(a,b,c, )") == "func(a, b, c,)"
#     @test format("func( a,b,c    )") == "func(a, b, c)"
#     @test format("func(a, b, c) ") == "func(a, b, c) "
#     @test format("func(a, b; c)") == "func(a, b; c)"
#     @test format("func(  a, b; c)") == "func(a, b; c)"
#     @test format("func(a  ,b; c)") == "func(a, b; c)"
#     @test format("func(a=1,b; c=1)") == "func(a = 1, b; c = 1)"
# end

    @testset "indents" begin
        @testset "begin" begin
            str = """
begin
    arg
end"""
            @test format("""
                begin
                arg
                end""") == str
            @test format("""
                begin
                    arg
                end""") == str
            @test format("""
                begin
                    arg
                end""") == str
            @test format("""
                begin
                        arg
                end""") == str
            str = """
    begin
        begin
            arg
        end
    end"""
            @test format("""
                begin
                begin
                arg
                end
                end""") == str
            @test format("""
                begin
                            begin
                arg
                end
                end""") == str
            @test format("""
                begin
                            begin
                arg
                        end
                end""") == str
        end
    end

    @testset "quote" begin
        str = """
    quote
        arg
    end"""
        @test format("""
    quote
        arg
    end""") == str
        @test format("""
    quote
    arg
    end""") == str
        @test format("""
    quote
            arg
        end""") == str
    end

    @testset "do" begin
        str = """
    map(args) do x
        y = 20
        return x * y
    end"""

        @test format("""
    map(args) do x
      y = 20
                        return x * y
        end""") == str

    end

    @testset "for" begin
        str = """
    for iter in I
        arg
    end"""
        @test format("""
    for iter in I
        arg
    end""") == str
        @test format("""
    for iter in I
    arg
    end""") == str
        @test format("""
    for iter in I
      arg
    end""") == str

        str = """
    for iter in I, iter2 in I2
        arg
    end"""
        @test format("""
    for iter in I, iter2 in I2
        arg
    end""") == str
        @test format("""
    for iter in I, iter2 in I2
    arg
    end""") == str
        @test format("""
    for iter in I, iter2 in I2
            arg
        end""") == str

        str = """
    for iter in I, iter2 in I2
        arg
    end"""
        @test format("""
    for iter=I, iter2 in I2
        arg
    end""") == str
        @test format("""
    for iter =I, iter2 in I2
        arg
    end""") == str
        @test format("""
    for iter =I, iter2 in I2
        arg
    end""") == str
        @test format("""
    for iter = I, iter2 = I2
        arg
    end""") == str
    end

    @testset "while" begin
        str = """
    while cond
        arg
    end"""
        @test format("""
    while cond
        arg
    end""") == str
        @test format("""
    while cond
    arg
    end""") == str
        @test format("""
    while cond
            arg
        end""") == str
    end

    @testset "let" begin
        str = """
    let x = X
        arg
    end"""
        @test format("""
    let x=X
        arg
    end""") == str
        @test format("""
    let x=X
    arg
    end""") == str
        @test format("""
    let x=X
        arg
    end""") == str
        str = """
    let x = X, y = Y
        arg
    end"""
        @test format("""
    let x = X, y = Y
        arg
    end""") == str
        @test format("""
    let x = X, y = Y
    arg
    end""") == str

        str = """
    y, back = let
        body
    end"""
        @test format("""
    y,back = let
      body
    end""") == str
    end

    @testset "struct" begin
        str = """
    struct name
        arg
    end"""
        @test format("""
    struct name
        arg
    end""") == str
        @test format("""
    struct name
    arg
    end""") == str
        @test format("""
    struct name
            arg
        end""") == str
    end

    @testset "mutable struct" begin
        str = """
    mutable struct name
        arg
    end"""
        @test format("""
    mutable struct name
        arg
    end""") == str
        @test format("""
    mutable struct name
    arg
    end""") == str
        @test format("""
    mutable struct name
            arg
        end""") == str
    end

    @testset "try-catch" begin
        str = """
    try
        arg
    catch
        arg
    end"""
        @test format("""
    try
        arg
    catch
        arg
    end""") == str
        @test format("""
    try
    arg
    catch
    arg
    end""") == str
        @test format("""
    try
            arg
        catch
            arg
        end""") == str
        str = """
    try
        arg
    catch
        arg
    end"""
        @test format("""
    try
        arg
    catch
        arg
    end""") == str
        @test format("""
    try
    arg
    catch
    arg
    end""") == str
        @test format("""
    try
            arg
        catch
            arg
        end""") == str

        str = """
    try
        arg
    catch err
        arg
    end"""
        @test format("""
    try
        arg
    catch err
        arg
    end""") == str
        @test format("""
    try
    arg
    catch err
    arg
    end""") == str
        @test format("""
    try
            arg
        catch err
            arg
        end""") == str
    end

# @testset "docs" begin
#     str = """
#     \"""
#     doc
#     \"""
#     function f()
#         20
#     end"""

#     @test format("""
#     \"""doc
#     \"""
#     function f()
#         20
#     end""") == str
#     @test format("""
#     \"""
#     doc\"""
#     function f()
#         20
#     end""") == str
#     @test format("""
#     \"""doc\"""
#     function f()
#         20
#     end""") == str

#     @test format("""
#     "doc
#     "
#     function f()
#         20
#     end""") == str
#     @test format("""
#     "
#     doc"
#     function f()
#         20
#     end""") == str
#     @test format("""
#     "doc"
#     function f()
#         20
#     end""") == str

#     # tests indentation and correctly formatting a docstring with escapes
#     str = """
#        begin
#            \"""
#                f

#            docstring for f
#            :(function \$(dict[:name]){\$(all_params...)}(\$(dict[:args]...);
#                                                 \$(dict[:kwargs]...))::\$rtype
#            \$(dict[:body])
#            \"""
#            function f()
#                100
#            end
#        end"""
#     @test format("""
#        begin
#        \"""

#            f

#        docstring for f
#        :(function \$(dict[:name]){\$(all_params...)}(\$(dict[:args]...);
#                                             \$(dict[:kwargs]...))::\$rtype
#        \$(dict[:body])

#        \"""
#        function f()
#            100
#        end
#        end""") == str
# end

end


text:
using BetaVQE, Yao, YaoExtensions
using Test, Random, StatsBase
using Zygote
using BitBasis
using VAN

@testset "sample" begin
    Random.seed!(3)
    nbits = 4
    nhiddens = [10, 20]
    nsamples = 1000
    β = 1.0

    h = heisenberg(nbits)
    c = dispatch!(variational_circuit(nbits), :random)
    model = AutoRegressiveModel(nbits, nhiddens)

    configs = bitarray(collect(0:(1<<nbits-1)), nbits)
    logp = get_logp(model, configs)
    @test isapprox(sum(exp.(logp)), 1.0, rtol=1e-2)

    f = sum(exp.(logp) .* free_energy_local(β, h, model, c, configs))

    samples = gen_samples(model, nsamples)
    f_sample = free_energy(β, h, model, c, samples)
    @test isapprox(f, f_sample, rtol=1e-2)
end

@testset "circuit diff" begin
    Random.seed!(3)
    nbits = 4
    nhiddens = [10]
    nsamples = 2000

    h = heisenberg(nbits)
    c = dispatch!(variational_circuit(nbits), :random)
    model = AutoRegressiveModel(nbits, nhiddens)
    samples = gen_samples(model, nsamples)

    # check the gradient of circuit parameters
    params = parameters(c)
    ϵ = 1e-5
    for k in 1:length(params)
        params[k] -= ϵ
        dispatch!(c, params)
        l1 = free_energy(2.0, h, model, c, samples)
        params[k] += 2ϵ
        dispatch!(c, params)
        l2 = free_energy(2.0, h, model, c, samples)
        params[k] -= ϵ
        dispatch!(c, params)
        g = (l2-l1)/2ϵ
        g2 = gradient(c->free_energy(2.0, h, model, c, samples), c)[1]
        @test isapprox(g, g2[k], rtol=1e-2)
    end
end

@testset "network diff" begin
    Random.seed!(3)
    nbits = 2
    nhiddens = [10]
    nsamples = 1000

    h = heisenberg(nbits)
    c = dispatch!(variational_circuit(nbits), :random)
    model = AutoRegressiveModel(nbits, nhiddens)

    ϵ = 1e-5
    # check the gradient of model
    configs = bitarray(collect(0:(1<<nbits-1)), nbits)
    function f(model)
        logp = get_logp(model, configs)
        sum(exp.(logp) .* free_energy_local(2.0, h, model, c, configs))
    end

    m, n = 1, 1
    params = model_parameters(model)
    params[m][n] -= ϵ
    model_dispatch!(model, params)
    l1 = f(model)
    params[m][n] += 2ϵ
    model_dispatch!(model, params)
    l2 = f(model)
    g = (l2-l1)/2ϵ

    #tune it back
    params[m][n] -= ϵ
    model_dispatch!(model, params)
    samples = gen_samples(model, nsamples)
    g2 = gradient(model->free_energy(2.0, h, model, c, samples), model)[1]
    @test isapprox(g, g2[m][n], rtol=1e-1)
    @show g, g2[m][n]
end

@testset "tns circuit diff" begin
    Random.seed!(3)
    nx = 2
    ny = 2
    nbits = nx*ny
    depth = 3
    nhiddens = [10]
    nsamples = 2000

    h = heisenberg(nbits)
    c = tns_circuit(nbits, depth, pair_square(nx, ny; periodic=false); entangler=(n,i,j)->put(n,(i,j)=>general_U4(rand(15)*2π)))
    model = AutoRegressiveModel(nbits, nhiddens)
    samples = gen_samples(model, nsamples)

    # check the gradient of circuit parameters
    params = parameters(c)
    ϵ = 1e-5
    for k in 1:length(params)
        params[k] -= ϵ
        dispatch!(c, params)
        l1 = free_energy(2.0, h, model, c, samples)
        params[k] += 2ϵ
        dispatch!(c, params)
        l2 = free_energy(2.0, h, model, c, samples)
        params[k] -= ϵ
        dispatch!(c, params)
        g = (l2-l1)/2ϵ
        g2 = gradient(c->free_energy(2.0, h, model, c, samples), c)[1]
        @test isapprox(g, g2[k], atol=1e-2)
    end
end

ext: jl


text:
module DashlessDreamBlocks

using ..Ahorn, Maple

# Add DashlessDreaming option to Map Metadata and Change Inventory Trigger
if "DashlessDreaming" ∉ Maple.inventories
    push!(Maple.inventories, "DashlessDreaming")
end

if "DashlessDreaming (No Backpack)" ∉ Maple.inventories
    push!(Maple.inventories, "DashlessDreaming (No Backpack)")
end

end

max_stars_repo_name: coloursofnoise/DashlessDreamBlocks

max_issues_repo_name: coloursofnoise/DashlessDreamBlocks

max_forks_repo_name: coloursofnoise/DashlessDreamBlocks


text:
## A domain representing a union of subdomains

export UnionDomain

"""
    UnionDomain represents a union of multiple subdomains.
"""
immutable UnionDomain{DD,T,d} <: Domain{T,d}
    domains::DD
end

UnionDomain(d::Tuple) =
    UnionDomain{typeof(d),mapreduce(eltype,promote_type,d),mapreduce(dimension,max,d)}(d)
UnionDomain(d::AbstractVector)=UnionDomain(tuple(d...))

UnionDomain(d1::UnionDomain,d2::UnionDomain)=UnionDomain((d1.domains...,d2.domains...))
UnionDomain(d1::Domain,d2::UnionDomain)=UnionDomain((d1,d2.domains...))
UnionDomain(d1::UnionDomain,d2::Domain)=UnionDomain((d1.domains...,d2))

UnionDomain(d1::Domain,d2::Domain)=UnionDomain((d1,d2))

canonicaldomain(d::UnionDomain)=d  # we could map all to canonical, but then there would be overlap

isambiguous(d::UnionDomain)=isempty(d.domains)
Base.convert{DD,T,d}(::Type{UnionDomain{DD,T,d}},::AnyDomain)=UnionDomain{DD,T,d}(map(D->D(AnyDomain()),DD.parameters))
Base.convert{IT<:UnionDomain}(::Type{IT},::AnyDomain)=UnionDomain(tuple())

Base.union(d::Domain) = d
Base.union{D<:Domain}(d::AbstractVector{D}) = UnionDomain(d)
function Base.union{D<:Domain}(::Type{D},x)
    out = map(D,x)
    length(out) > 1 ? ∪(out) : out[1]
end
function Base.union{D<:Domain}(::Type{D},x,y)
    out = map(D,x,y)
    length(out) > 1 ? ∪(out) : out[1]
end
#TODO Check for intersection

Base.union(d1::EmptyDomain,d2::EmptyDomain)=d1
Base.union(d1::EmptyDomain,d2::Domain)=d2
Base.union(d1::Domain,d2::EmptyDomain)=d1

function Base.union(d1::Domain,d2::Domain)
    if d1==d2
        return d1
    end

    Γ=d1∩d2
    if isempty(Γ)
        UnionDomain(d1,d2)
    else
        (d1\Γ)∪Γ∪(d2\Γ)
    end
end

Base.intersect(d1::UnionDomain,d2::UnionDomain)=mapreduce(d->d1∩d,∪,d2.domains)
Base.intersect(d1::Domain,d2::UnionDomain)=mapreduce(d->d1∩d,∪,d2.domains)
Base.intersect(d1::UnionDomain,d2::Domain)=mapreduce(d->d2∩d,∪,d1.domains)

Base.setdiff(a::UnionDomain,b::UnionDomain) = mapreduce(d->setdiff(d,b),∪,a.domains)
Base.setdiff(a::UnionDomain,b::Domain) = mapreduce(d->setdiff(d,b),∪,a.domains)
Base.setdiff(a::Domain,b::UnionDomain) = mapreduce(d->setdiff(a,d),∩,b.domains)

Base.sort(d::UnionDomain;opts...) = UnionDomain(sort([d.domains...];opts...))

for op in (:(Base.first),:(Base.last))
    @eval $op(d::UnionDomain) = $op($op(d.domains))
end

#support tuple set
for OP in (:(Base.start),:(Base.done),:(Base.endof),:(Base.getindex),:(Base.length),:(Base.next))
    @eval $OP(S::UnionDomain,k...) = $OP(S.domains,k...)
end

pieces(d::UnionDomain) = [d.domains...]
numpieces(d::UnionDomain) = length(d.domains)

arclength(d::UnionDomain) = mapreduce(arclength,+,d.domains)

==(d1::UnionDomain,d2::UnionDomain) =
    length(d1)==length(d2)&&all(Bool[d1[k]==d2[k] for k=1:length(d1)])

Base.in(x,d::UnionDomain) = any(a->x∈a,d.domains)
Base.issubset(a::Domain,d::UnionDomain) = (a∪d)==d
Base.reverse(d::UnionDomain) = UnionDomain(reverse(map(reverse,d.domains)))

∂(d::UnionDomain) = mapreduce(∂,union,d.domains)

function points(d::UnionDomain,n)
   k=div(n,length(d))
    r=n-length(d)*k

    [vcat([points(d.domains[j],k+1) for j=1:r]...);
        vcat([points(d.domains[j],k) for j=r+1:length(d)]...)]
end

Base.rand(d::UnionDomain)=rand(d[rand(1:length(d))])
checkpoints(d::UnionDomain)=mapreduce(checkpoints,union,d.domains)

function Base.merge(d1::UnionDomain,m::Interval)
    ret=d1.domains

    for k=length(ret):-1:1
        it=intersect(ret[k],m)
        if !isempty(it)
            sa=setdiff(ret[k],it)
            m=setdiff(m,it)
            if isempty(sa)
                ret = [ret[1:k-1]...;it;ret[k+1:end]...]
            else
                ret = [ret[1:k-1]...;sa;it;ret[k+1:end]...]
            end
            if isempty(m)
                break
            end
        end
    end
    @assert isempty(m)
    UnionDomain(sort!(ret,by=first))
end

function Base.merge(d1::UnionDomain,d2::UnionDomain)
    ret=d1
    for m in d2.domains
        ret=merge(ret,m)
    end
    ret
end

for op in (:*,:+,:-,:.*,:.+,:.-)
    @eval begin
        $op(c::Number,d::UnionDomain)=UnionDomain(map(a->$op(c,a),d.domains))
        $op(d::UnionDomain,c::Number)=UnionDomain(map(a->$op(a,c),d.domains))
    end
end
/(d::UnionDomain,c::Number) = UnionDomain(map(a->a/c,d.domains))


text:
module MLJAbstractGPsGlue

using AbstractGPs
using MLJModelInterface
using Optim
using ParameterHandling
using Zygote

import MLJModelInterface:
    fit,
    fitted_params,
    predict,
    predict_mean,
    matrix,
    JointProbabilistic

mutable struct MLJAbstractGP{T, V} <: JointProbabilistic
    initial_parameters::T
    build_gp::V
end

function MLJAbstractGP(;
    initial_gp_parameters=__default_gp_parameters,
    build_gp=__default_build_gp,
    initial_noise_variance::Real=1.0,
)
    if initial_noise_variance <= 0
        throw(error("noise variance must be positive."))
    end
    if !(build_gp(ParameterHandling.value(initial_gp_parameters)) isa AbstractGPs.AbstractGP)
        throw(error("build_gp doesn't appear to build an AbstractGP."))
    end

    return MLJAbstractGP(
        (
            gp_parameters=initial_gp_parameters,
            noise_variance=positive(initial_noise_variance),
        ),
        build_gp,
    )
end

MLJModelInterface.clean!(model::MLJAbstractGP) = ""

# The default choise is a straightforward GP with an Exponentiated Quadratic kernel.
const __default_gp_parameters = (
    λ = bounded(1.0, 1e-2, 1e2),
    σ² = bounded(1.0, 1e-2, 1e2),
)

__default_build_gp(θ) = GP(θ.σ² * SEKernel() ∘ ScaleTransform(θ.λ))

# This method currently just assumes that `X` is matrix-like. Probably this can be refined
# to ensure that the correct type gets used in the correct situation.
function fit(model::MLJAbstractGP, verbosity, X, y::AbstractVector{<:Real})

    # Convert inputs into a type that `AbstractGPs` understands.
    x = ColVecs(collect(matrix(X; transpose=true)))

    # Ensure that the inputs and targets are the same length.
    if length(x) != length(y)
        throw(error("number of inputs not the same as number of outputs"))
    end

    # Get flat parameters and functionality to reconstruct the unflattened counterpart.
    flat_initial_params, unflatten = flatten(model.initial_parameters)

    # Specify functionality to unpack and strip out all ParameterHandling-related data.
    unpack = ParameterHandling.value ∘ unflatten

    # Specify objective function.
    function objective(params)
        f = model.build_gp(params.gp_parameters)
        return -logpdf(f(x, params.noise_variance + 1e-3), y)
    end

    # Use Optim.jl to optimise the hyperparameters. We're very opinionated and use BFGS.
    training_results = Optim.optimize(
        objective ∘ unpack,
        θ -> only(Zygote.gradient(objective ∘ unpack, θ)),
        flat_initial_params,
        BFGS(
            alphaguess = Optim.LineSearches.InitialStatic(scaled=true),
            linesearch = Optim.LineSearches.BackTracking(),
        ),
        Optim.Options(show_trace = verbosity > 0);
        inplace=false,
    )

    # Extract parameters and construct the posterior at the optimum.
    final_params = unpack(training_results.minimizer)
    fx = model.build_gp(final_params.gp_parameters)(x, final_params.noise_variance + 1e-3)
    f_post = posterior(fx, y)

    # Compile thing to return and return them.
    fit_result = (
        posterior=f_post,
        noise_variance=final_params.noise_variance,
        final_params=final_params,
    )
    cache = nothing
    report = (training_results=training_results, final_params=final_params)
    return fit_result, cache, report
end

fitted_params(::MLJAbstractGP, fit_result) = fit_result.final_params

function predict(model::MLJAbstractGP, fit_result, X_new)

    # Convert inputs into a type that `AbstractGPs` understands.
    x_new = ColVecs(collect(matrix(X_new; transpose=true)))

    # Produce a posterior prediction. This is a FiniteGP, which is a multivariate Normal.
    return fit_result.posterior(x_new, fit_result.noise_variance + 1e-3)
end

function predict_mean(model::MLJAbstractGP, fit_result, X_new)
    return mean(predict(model, fit_result, X_new))
end

MLJModelInterface.metadata_pkg(
    MLJAbstractGP;
    name="MLJAbstractGPsGlue.jl",
    uuid="8b53f75a-7fc5-4a6e-98d3-d4400dab8eec",
    url="https://github.com/willtebbutt/MLJAbstractGPsGlue.jl/",
    julia=true,
    license="MIT",
    is_wrapper=true,
)

MLJModelInterface.metadata_model(
    MLJAbstractGP;
    target_scitype=AbstractVector{MLJModelInterface.Continuous},
    supports_weights=false,
    descr="Vanilla GP regression using any model in the AbstractGPs interface.",
    load_path="MLJAbstractGPsGlue.MLJAbstractGP",
)

logpdf_loss(fx, y) = -logpdf(fx, y)

export MLJAbstractGP, logpdf_loss

end


text:
"""
    commasplit(line: String) -> String[]

Return a line as a vector, splitting on a comma.

This is used for **@piping.**

**Example**
```julia
arrowsplit("a,b")  # returns ["a", "b"]
```
"""
commasplit(line) = split(line, ",")


text:
"""
    testapply(tfm, item)
    testapply(tfm, I)

Test `apply` invariants of `tfm` on `item` or item type `I`.

1. With a constant `randstate` parameter, `apply` should always return the
    same result.
"""
function testapply(tfm::Transform, item::AbstractItem)
    # Invariant 1
    r = getrandstate(tfm)
    titems = [apply(tfm, item; randstate = r) for i = 1:8]
    @test all(map(titem -> itemdata(titem) == itemdata(titems[1]), titems))

    #
    @test_nowarn apply(tfm, (item, item))
end

testapply(tfm::Transform, I::Type{<:AbstractItem}) = testapply(tfm, testitem(I))
testapply(tfm, items::Tuple) = foreach(i -> testapply(tfm, i), items)

"""
    testapply!(tfm, Items)
    testapply!(tfm, Item)
    testapply!(tfm, item1, item2)

Test `apply!` invariants.

1. With a constant `randstate` parameter, `apply!` should always return the
    same result.
2. Given a different item than was used to create the buffer, the buffer's data
    should be modified.
"""
function testapply!(tfm::Transform, item1::I, item2::I) where I<:AbstractItem
    # Invariant 1
    r = getrandstate(tfm)
    titems = [apply(tfm, deepcopy(item1); randstate = r) for i = 1:8]
    @test allequal(itemdata.(titems))

    # Invariant 2
    buf = makebuffer(tfm, item1)
    cbuf = deepcopy(buf)
    apply!(buf, tfm, item2)
    if buf isa AbstractItem
        @test itemdata(buf) != itemdata(cbuf)
    end
end

testapply!(tfm::Transform, I::Type{<:AbstractItem}) = testapply!(tfm, testitem(I), testitem(I))
testapply!(tfm, items::Tuple) = foreach(i -> testapply!(tfm, i), items)

"""
    testprojective(tfm)

Test invariants of a `ProjectiveTransform`.

1. `getprojection` is defined, and, given a constant `randstate` parameter,
    always returns the same result.
2. It preserves the item type, i.e. `apply(tfm, ::I) -> I`.
3. Applying it to multiple items with the same bounds results in the same bounds
    for all items.
"""
function testprojective(tfm::ProjectiveTransform, items::Tuple)
    # All bounds must be equal for the test to work
    @assert allequal(getbounds.(items))

    # Invariant 1
    r = getrandstate(tfm)
    bs = getbounds(items[1])
    Ps = [getprojection(tfm, bs; randstate = r) for i = 1:10]
    @test allequal(Ps)

    # Invariant 2
    titems = apply(tfm, items)
    @test all(typeof.(items) .== typeof.(titems))

    # Invariant 3
    @test allequal(getbounds.(titems))
end

function testprojective(tfm::ProjectiveTransform, Is::NTuple{N, <:Type}) where {N}
    testprojective(tfm, testitem.(Is))
end

testprojective(tfm::ProjectiveTransform) =
    testprojective(tfm, (Image, MaskBinary, MaskMulti, Keypoints))

"""
    testitem(TItem)

Create an instance of an item with type `TItem`. If it has spatial bounds,
should return an instance with bounds with ranges (1:16, 1:16).
"""
function testitem end

testitem(::Type{ArrayItem}) = testitem(ArrayItem{2, Float32})
testitem(::Type{ArrayItem{N, T}}) where {N, T} = ArrayItem(rand(T, ntuple(i -> 16, N)))

testitem(::Type{Image}) = testitem(Image{2, RGB{N0f8}})
testitem(::Type{Image{N, T}}) where {N, T} = Image(rand(T, ntuple(i -> 16, N)))

testitem(::Type{MaskBinary}) = testitem(MaskBinary{2})
testitem(::Type{MaskBinary{N}}) where {N} = MaskBinary(rand(Bool, ntuple(i -> 16, N)))

testitem(::Type{MaskMulti}) = testitem(MaskMulti{2, UInt8})
function testitem(::Type{MaskMulti{N, T}}) where {N, T}
    n = rand(2:10)
    data = T.(rand(1:n, ntuple(i -> 16, N)))
    MaskMulti(data, 1:n)
end

testitem(::Type{Keypoints}) = testitem(Keypoints{2, Float32})
function testitem(::Type{Keypoints{N, T}}) where {N, T}
    n = rand(8:16)
    data = map(v -> v .* 15, rand(SVector{N, T}, n))
    return Keypoints(data, (16, 16))
end

testitem(::Type{Polygon}) = testitem(Polygon{2, Float32})
function testitem(::Type{Polygon{N, T}}) where {N, T}
    n = rand(8:16)
    data = map(v -> v .* 15, rand(SVector{N, T}, n))
    return Polygon(Keypoints(data, (16, 16)))
end

testitem(::Type{BoundingBox}) = testitem(BoundingBox{2, Float32})
function testitem(::Type{BoundingBox{N, T}}) where {N, T}
    n = 2
    data = map(v -> v .* 15, rand(SVector{N, T}, n))
    return BoundingBox(Keypoints(data, (16, 16)))
end

allequal(xs) = all(x == xs[1] for x in xs)


text:
getTreeData(m::Nothing, simple::Bool=false) = Tuple{String, Int, Int, Int, Int}[]
function getTreeData(m::Maple.Map, simple::Bool=get(config, "use_simple_room_values", true))
    data = Tuple{String, Int, Int, Int, Int}[]

    for room in m.rooms
        if simple
            push!(data, (room.name, round.(Int, room.position ./ 8)..., round.(Int, room.size ./ 8)...))

        else
            push!(data, (room.name, room.position..., room.size...))
        end
    end

    return data
end


text:
using Mosek
using Test

issue188() =
    maketask() do task
        appendvars(task,6)
        appendcone(task,MSK_CT_QUAD,0.0,[1,2,3])
        appendcone(task,MSK_CT_RQUAD,0.0,[4,5,6])

        removecones(task,[1])
        (ct,cpar,nummem) = getconeinfo(task,1)

        @test ct == MSK_CT_RQUAD
    end

@testset "[Github issues]" begin
    issue188()
end


text:
using Jacobi

type Basis2d
    Q::Int
    N::Int
    NB::Int
    NI::Int
    eindx::Array{Int,2}
    vindx::Array{Int,1}
    z::Array{Float64,1}
    w::Array{Float64,1}
    D::Array{Float64,2}
    t2bi_map::Array{Int,1}
    bi2t_map::Array{Int,1}

    function Basis2d(q::Int)
        n = q*q
        nb = 4*(q-1)
        ni = n - nb
        idx = reshape(1:n, q, q)
        eindx = zeros(Int, q, 4)
        eindx[:,1] = idx[:,1]
        eindx[:,2] = idx[q,:]
        eindx[:,3] = idx[:,q]
        eindx[:,4] = idx[1,:]
        vindx = [idx[1,1], idx[q,1], idx[q,q], idx[1,q]]

        z = Jacobi.zglj(q)
        w = Jacobi.wglj(z)
        D = Jacobi.dglj(z)
        m = zeros(Int, q*q)
        x = reshape(1:n,q,q)
        m[1] = x[1,1]
        m[2] = x[q,1]
        m[3] = x[q,q]
        m[4] = x[1,q]
        p = q-1
        if (q > 2)
            r = [1:(q-2)]
            nr = length(r)
            m[4+r] = x[2:p,1]
            m[4+nr+r] = x[q,2:p]
            m[4+2nr+r] = x[p:-1:2,q]
            m[4+3nr+r] = x[1,p:-1:2]
            m[(4+4nr+1):end] = reshape(x[2:p,2:p], (q-2)*(q-2))
        end
        m2 = zeros(Int,q*q)
        m2[m[1:n]] = [1:n]

        new(q, n, nb, ni, eindx, vindx, z, w, D, m, m2)
    end
end

nquad(b::Basis2d) = b.Q
nnodes(b::Basis2d) = b.z
weights(b::Basis2d) = b.w
diffmat(b::Basis2d) = b.D

mapt2bi(b::Basis2d, x) = x[b.t2bi_map]
mapt2b(b::Basis2d, x) = x[b.t2bi_map[1:b.NB]]
mapt2i(b::Basis2d, x) = x[b.t2bi_map[(b.NB+1):end]]
mapbi2t(b::Basis2d, xbi) = xbi[b.bi2t_map]

function mapt2bi!(b::Basis2d, x, xbi)
    m = b.t2bi_map
    for i = 1:b.N
        xbi[i] = x[m[i]]
    end
end

function mapt2b!(b::Basis2d, x, xbi)
    m = b.t2bi_map
    for i = 1:b.NB
        xbi[i] = x[m[i]]
    end
end

function mapt2i!(b::Basis2d, x, xi)
    m = b.t2bi_map
    for i = 1:b.NI
        xi[i] = x[m[i+b.NB]]
    end
end

function mapbi2t!(b::Basis2d, xbi, x)
    m = b.bi2t_map
    for i = 1:b.N
        x[i] = xbi[m[i]]
    end
end

using Mesh2d
import Base.LinAlg.BLAS
using Base.LinAlg.BLAS
using Devectorize
import Mesh2d
using Mesh2d

function deriv_a!(basis::Basis2d, r1, f, r2, da)
    gemm!('N', 'N', r1, basis.D, f, r2, da)
end

function deriv_a(basis::Basis2d, r1, f)
    da = Array(Float64,basis.Q, basis.Q)
    deriv_a!(basis, r1, f, 0.0, da)
    return da
end

function deriv_b!(basis::Basis2d, r1, f, r2, db)
    gemm!('N', 'T', r1, f, basis.D, r2, db)
end

function deriv_b(basis::Basis2d, r1, f)
    db = Array(Float64,basis.Q, basis.Q)
    deriv_b!(basis, r1, f, 0.0, db)
end

type Element2d

    Q::Int
    N::Int
    basis::Basis2d
    w::Array{Float64,1}
    z::Array{Float64,1}
    D::Array{Float64,2}
    x::Array{Float64,2}
    y::Array{Float64,2}
    dadx::Array{Float64,2}
    dady::Array{Float64,2}
    dbdx::Array{Float64,2}
    dbdy::Array{Float64,2}
    jac::Array{Float64,2}
    mass::Array{Float64,2}
    sjac::Array{Float64,2}
    smass::Array{Float64,2}
    nx::Array{Float64,2}
    ny::Array{Float64,2}
    curved::Bool

    function Element2d(basis::Basis2d)

        Q = basis.Q
        N = Q*Q
        w = basis.w
        z = basis.z
        D = basis.D
        x = zeros(Float64,Q,Q)
        y = zeros(Float64,Q,Q)
        dadx = zeros(Float64,Q,Q)
        dady = zeros(Float64,Q,Q)
        dbdx = zeros(Float64,Q,Q)
        dbdy = zeros(Float64,Q,Q)
        jac = zeros(Float64,Q,Q)
        mass = zeros(Float64,Q,Q)
        sjac = zeros(Float64,Q,4)
        smass = zeros(Float64,Q,4)
        nx = zeros(Float64,Q,4)
        ny = zeros(Float64,Q,4)
        curved = false

        new(Q, N, basis, w, z, D, x, y, dadx, dady, dbdx, dbdy,
            jac, mass, sjac, smass, nx, ny, curved)
    end
end

function Element2d(basis::Basis2d, quad::Mesh2d.Quad, crvs=[])

    el = Element2d(basis)
    element_setup(el, quad, crvs)
    return el
end

function standard_element(basis::Basis2d)

    el = Element2d(basis)
    Q = el.Q
    N = el.N

    el.jac[:] = 1.0
    el.dadx[:] = 1.0
    el.dady[:] = 0.0
    el.dbdx[:] = 0.0
    el.dbdy[:] = 1.0
    for i=1:Q, j=1:Q
        el.mass[j,i] = el.w[i]*el.w[j]
    end
    el.sjac[:] = 1.0

    for edge = 1:4, i=1:Q
        el.smass[i,edge] = el.w[i]
    end

    el.nx[:,1] = 0.0
    el.nx[:,2] = 1.0
    el.nx[:,3] = 0.0
    el.nx[:,4] = -1.0
    el.ny[:,1] = -1.0
    el.ny[:,2] = 0.0
    el.ny[:,3] = 1.0
    el.ny[:,4] = 0.0

    return el
end

function element_setup(el::Element2d, quad, crvs=[])
    # Calculate node coords:
    basis = el.basis
    node_coords(el.basis, quad, el.x, el.y, crvs)
    Q = el.Q
    x = el.x
    y = el.y
    el.curved = quad.curved

    dxda = Array(Float64, Q, Q)
    dyda = Array(Float64, Q, Q)
    dxdb = Array(Float64, Q, Q)
    dydb = Array(Float64, Q, Q)

    deriv_a!(basis, 1.0, x, 0.0, dxda)
    deriv_b!(basis, 1.0, x, 0.0, dxdb)
    deriv_a!(basis, 1.0, y, 0.0, dyda)
    deriv_b!(basis, 1.0, y, 0.0, dydb)

    @devec el.jac = dxda .* dydb .- dxdb .* dyda
    @devec el.dadx =  dydb ./ el.jac
    @devec el.dady = -dxdb ./ el.jac
    @devec el.dbdx = -dyda ./ el.jac
    @devec el.dbdy =  dxda ./ el.jac

    for i=1:Q, j=1:Q
        el.mass[j,i] = el.w[i]*el.w[j]*el.jac[j,i]
    end

    # Calculate surface parameters
    sjac = el.sjac
    # Surface Jacobian
    @devec el.sjac[:,1] = dxda[:,1] .* dxda[:,1] .+ dyda[:,1] .* dyda[:,1]
    @devec el.sjac[:,2] = dxdb[Q,:] .* dxdb[Q,:] .+ dydb[Q,:] .* dydb[Q,:]
    @devec el.sjac[:,3] = dxda[:,Q] .* dxda[:,Q] .+ dyda[:,Q] .* dyda[:,Q]
    @devec el.sjac[:,4] = dxdb[1,:] .* dxdb[1,:] .+ dydb[1,:] .* dydb[1,:]

    @devec el.sjac = sqrt(el.sjac)

    for edge = 1:4, i=1:Q
        el.smass[i,edge] = el.w[i]*el.sjac[i,edge]
    end

    # Compute normals:
    xv = quad.verts[:,1]
    yv = quad.verts[:,2]
    icrv = quad.curve
    vine = [1 2 3 4; 2 3 4 1]
    for edge = 1:4
        ei = sub(basis.eindx, :, edge)
        v1 = vine[1,edge]
        v2 = vine[2,edge]
        icrv = quad.curve[edge]
        if icrv == 0
            nxy = Mesh2d.normal(xv[v1], yv[v1], xv[v2], yv[v2])
            for i = 1:Q
                el.nx[i,edge] = nxy[1]
                el.ny[i,edge] = nxy[2]
            end
        else
            for i = 1:Q
                el.nx[i,edge], el.ny[i, edge] = Mesh2d.normal(crvs[icrv], x[ei[i]], y[ei[i]])
            end
        end
    end
end

function node_coords(b::Basis2d, mshel, x, y, crvs)
    Q = b.Q
    N = b.N
    z = b.z
    xv = mshel.verts[:,1]
    yv = mshel.verts[:,2]
    icrv = mshel.curve
    vine = [1 2 4 1; 2 3 3 4]
    for edge = 1:4
        ei = sub(b.eindx, :, edge)
        v = vine[:,edge]
        if icrv[edge] == 0
            x[ei], y[ei] = Mesh2d.coords(z, xv[v[1]], yv[v[1]], xv[v[2]], yv[v[2]], true)
        else
            x[ei], y[ei] = Mesh2d.coords(crvs[icrv[edge]], z, xv[v[1]], yv[v[1]],
                          xv[v[2]], yv[v[2]],  true)
        end
    end

    Mesh2d.gordon_hall(x, y, z)
end

function deriv_x!(el::Element2d, f, dx, ws)
    b = el.basis
    deriv_a!(b, 1.0, f, 0.0, dx)
    deriv_b!(b, 1.0, f, 0.0, ws)
    for i = 1:length(f)
        dx[i] = dx[i] * el.dadx[i] + ws[i] * el.dbdx[i]
    end
end

function deriv_x(el::Element2d, f)

    local ws = similar(f)
    dx = similar(f)
    println(dx)
    deriv_x!(el, f, dx, ws)
    return dx
end

function deriv_y!(el::Element2d, f, dy, ws)
    b = el.basis
    deriv_a!(b, 1.0, f, 0.0, dy)
    deriv_b!(b, 1.0, f, 0.0, ws)
    for i = 1:length(f)
        dy[i] = dy[i] * el.dady[i] + ws[i] * el.dbdy[i]
    end
end

function deriv_y(el::Element2d, f)

    ws = similar(f)
    dy = similar(f)
    deriv_y!(el, f, dy, ws)
    return dy
end

function deriv_y(el::Element2d, f)

    b = el.basis
    Q = el.Q
    dy = deriv_a(b, 1.0, f)
    @devec dy = dy .* el.dady

    ws = deriv_b(b, 1.0, f)
    @devec dy = ws .* el.dbdy .+ dy

    return dy
end

function gradient!(el::Element2d, f, dx, dy)
    Q = el.Q
    da = zeros(Q,Q)
    db = zeros(Q,Q)

    deriv_a!(el.basis, 1.0, f, 0.0, da)
    deriv_b!(el.basis, 1.0, f, 0.0, db)

    for i = 1:el.N
        dx[i] = da[i] * el.dadx[i] + db[i] * el.dbdx[i]
        dy[i] = da[i] * el.dady[i] + db[i] * el.dbdy[i]
    end
end

function gradient(el::Element2d, f)
    Q = el.Q
    dx = zeros(Q,Q)
    dy = zeros(Q,Q)

    gradient!(el, f, dx, dy)

    return dx, dy
end

function laplace_matrix(elem::Element2d)
    Q = elem.Q
    N = elem.N
    L = zeros(Q,Q,Q,Q)
    A = zeros(Q,Q)

    D = elem.D
    m = elem.mass

    for i = 1:N
        A[i] = m[i] * (elem.dadx[i]*elem.dadx[i] + elem.dady[i]*elem.dady[i])
    end
    B = zeros(Q,Q)
    for i = 1:N
        B[i] = m[i] * (elem.dbdx[i]*elem.dbdx[i] + elem.dbdy[i]*elem.dbdy[i])
    end
    C = zeros(Q,Q)
    for i = 1:N
        C[i] = m[i] * (elem.dadx[i]*elem.dbdx[i] + elem.dady[i]*elem.dbdy[i])
    end
    for k = 1:Q
        for l = 1:Q
            for p = 1:Q
                for r = 1:Q
                    L[p,k,r,k] += A[l,k] * D[l,p] * D[l,r]
                    L[l,p,l,r] += B[l,k] * D[k,p] * D[k,r]
                    L[l,p,r,k] += C[l,k] * D[k,p] * D[l,r]
                    L[p,k,l,r] += C[l,k] * D[l,p] * D[k,r]
                end
            end
        end
    end
    return reshape(L,N,N)

end


text:
"""
    flatten(x::AbstractArray)

Reshape arbitrarly-shaped input into a matrix-shaped output,
preserving the size of the last dimension.

See also [`unsqueeze`](@ref).

# Examples
```jldoctest
julia> rand(3,4,5) |> Flux.flatten |> size
(12, 5)

julia> xs = rand(Float32, 10,10,3,7);

julia> m = Chain(Conv((3,3), 3=>4, pad=1), Flux.flatten, Dense(400,33));

julia> xs |> m[1] |> size
(10, 10, 4, 7)

julia> xs |> m |> size
(33, 7)
```
"""
function flatten(x::AbstractArray)
  return reshape(x, :, size(x)[end])
end

"""
    normalise(x; dims=ndims(x), ϵ=1e-5)

Normalise `x` to mean 0 and standard deviation 1 across the dimension(s) given by `dims`.
Per default, `dims` is the last dimension.
`ϵ` is a small additive factor added to the denominator for numerical stability.
"""
function normalise(x::AbstractArray; dims=ndims(x), ϵ=ofeltype(x, 1e-5))
  μ = mean(x, dims=dims)
    #   σ = std(x, dims=dims, mean=μ, corrected=false) # use this when Zygote#478 gets merged
  σ = std(x, dims=dims, corrected=false)
  return (x .- μ) ./ (σ .+ ϵ)
end

"""
 cos_embedding_loss(x1, x2, y; margin=0, pad=false)

 Finds the cosine distance between `x1` and `x2` matrices for `y` = 1 or -1.
 `margin` can take values from [-1,1].
"""

function cos_embedding_loss(x1, x2, y; margin=0, pad=false) where N
    @assert (margin <= 1 && margin >= -1)
    @assert y ∈ (1,-1)
    if (pad == false && (size(x1) != size(x2)))
        throw(DimensionMismatch("If you wish to calculate the loss by padding zeros, pass 'pad = true and add PaddedViews.jl to the environment'"))
    elseif (pad == true && (size(x1) != size(x2)))
        size(x1) > size(x2) ? x2 = PaddedView(0.0, x2, size(x1)) : x1 = PaddedView(0.0, x1, (size(x2)))
    end
    if (y == 1)
        return (1 - (dot(x1,x2) / (norm(x1) * norm(x2))))
    elseif (y == -1)
        return max(0, (( dot(x1,x2) / (norm(x1) * norm(x2)))-margin))
    end
end


text:
import Base: start, next, done
export aggregate

type Circle{T}
  xs::Vector{T}
  curr::Int
end

Circle(xs) = Circle(xs, 0)
(::Type{Circle{T}}){T}() = Circle(T[])

@forward Circle.xs Base.first, Base.last, Base.getindex, Base.push!

function next!(x::Circle)
  x.curr == length(x.xs) ?
    (x.curr = 1) :
    (x.curr += 1)
  return x.xs[x.curr]
end

type Spliterator{T, S, I}
  iter::T
  state::S
  chunk::I
  tasks::Circle{Task}
end

function Spliterator(iter)
  sub, state = chunk(iter, start(iter))
  s = Spliterator(iter, state, sub, Circle{Task}())
end

chunk(xs, state) =
  isempty(xs) ?
    (eltype(xs)[], 1):
    (eltype(xs)[xs[state]], state+1)

chunk!(s::Spliterator) =
  s.chunk, s.state = chunk(s.iter, s.state)

function next!(s::Spliterator)
  yieldto(next!(s.tasks))
  first(s.tasks) === current_task() && chunk!(s)
  return next(s.chunk, start(s.chunk))
end

start(s::Spliterator) = start(s.chunk)

done(s::Spliterator, state) =
  done(s.chunk, state) && done(s.iter, s.state)

next(s::Spliterator, state) =
  !done(s.chunk, state) ? next(s.chunk, state) : next!(s)

function splittask(xs::Spliterator, f, results)
  t = current_task()
  Task() do
    push!(results, f(xs))
    yieldto(last(xs.tasks) ≠ current_task() ? next!(xs.tasks) : t)
  end
end

function aggregate(xs, fs::Function...)
  xs = Spliterator(xs)
  results = []
  for f in fs
    push!(xs.tasks, splittask(xs, f, results))
  end
  yieldto(next!(xs.tasks))
  return results
end

function observer(id)
  function (xs)
    for x in xs
      println("$id sees $x")
    end
    return id
  end
end

# chunk(xs::Array, state) = xs, length(xs) + 1

# aggregate([:a, :b, :c], observer(1), observer(2))
#
# xs = collect(1:10^8)
#
# @time mean(xs)
# @time var(xs)
#
# @time aggregate(xs, mean, var)


text:
module ConstantFieldsTests

using Gridap.TensorValues
using Gridap.Arrays
using Gridap.Fields

for v in (3.0,VectorValue(1,2))
  f = v
  xi = Point(2,1)
  np = 4
  x = fill(xi,np)
  fx = fill(v,np)
  ∇fx = fill(zero(v[1]),np)
  test_field(f,x,fx,grad=∇fx)
end

for v in (3.0,VectorValue(1,2))
  f = [v,2*v,3*v]
  xi = Point(2,1)
  np = 4
  x = fill(xi,np)
  fx = repeat(f',np)
  ∇fx = fill(zero(v[1]),size(fx)...)
  test_field(f,x,fx,grad=∇fx)
end

end # module


text:
# Useful physical constants for dealing with water

# Critical point of water

"Critical density of water [kg m⁻³]"
const ρc = 322
"Critical temperature of water [K]"
const Tc = 647.096
"Critical pressure of water [Pa]"
const Pc = 22.06e6

# Molecular properties

"Specific gas constant [J mol⁻¹ K⁻¹]"
const R = 8.3144621
"Molar mass of water [kg mol⁻¹]"
const h2o_molar_mass = 0.01801528
"Specific gas constant for water [J kg⁻¹ K⁻¹]"
const R_h2o = 461.51805


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Base.Grisu

function trimrep(buffer)
    len = length(unsafe_string(pointer(buffer)))
    ind = len
    for i = len:-1:1
        buffer[i] != 0x30 && break
        ind -= 1
    end
    buffer[ind+1] = 0
    return unsafe_string(pointer(buffer))
end

const bufsize = 500
buffer = Array{UInt8}(bufsize)
fill!(buffer,0)
bignums = [Grisu.Bignums.Bignum(),Grisu.Bignums.Bignum(),Grisu.Bignums.Bignum(),Grisu.Bignums.Bignum()]

# Start by checking the byte-order.
ordered = 0x0123456789ABCDEF
@test 3512700564088504e-318 == reinterpret(Float64,ordered)

min_double64 = 0x0000000000000001
@test 5e-324 == reinterpret(Float64,min_double64)

max_double64 = 0x7fefffffffffffff
@test 1.7976931348623157e308 == reinterpret(Float64,max_double64)

# Start by checking the byte-order.
ordered = 0x01234567
@test Float32(2.9988165487136453e-38) == reinterpret(Float32,ordered)

min_float32 = 0x00000001
@test Float32(1.4e-45) == reinterpret(Float32,min_float32)

max_float32 = 0x7f7fffff
@test Float32(3.4028234e38) == reinterpret(Float32,max_float32)

ordered = 0x0123456789ABCDEF
diy_fp  = Grisu.Float(reinterpret(Float64,ordered))
@test UInt64(0x12) - UInt64(0x3FF) - 52 == diy_fp.e % UInt64
# The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64.
@test 0x0013456789ABCDEF== diy_fp.s

min_double64 = 0x0000000000000001
diy_fp  = Grisu.Float(reinterpret(Float64,min_double64))
@test -UInt64(0x3FF) - Int64(52) + Int64(1) == diy_fp.e % UInt64
# This is a denormal so no hidden bit.
@test 1 == diy_fp.s

max_double64 = 0x7fefffffffffffff
diy_fp  = Grisu.Float(reinterpret(Float64,max_double64))
@test 0x7FE - 0x3FF - 52 == diy_fp.e % UInt64
@test 0x001fffffffffffff== diy_fp.s

ordered = 0x01234567
diy_fp  = Grisu.Float(reinterpret(Float32,ordered))
@test UInt64(0x2) - UInt64(0x7F) - 23 == diy_fp.e % UInt64
# The 23 mantissa bits, plus the implicit 1 in bit 24 as a uint32_t.
@test 0xA34567 == UInt64(diy_fp.s)

min_float32 = 0x00000001
diy_fp  = Grisu.Float(reinterpret(Float32,min_float32))
@test -UInt64(0x7F) - 23 + 1 == diy_fp.e % UInt64
# This is a denormal so no hidden bit.
@test 1 == UInt64(diy_fp.s)

max_float32 = 0x7f7fffff
diy_fp  = Grisu.Float(reinterpret(Float32,max_float32))
@test 0xFE - 0x7F - 23 == diy_fp.e % UInt64
@test 0x00ffffff == UInt64(diy_fp.s)

ordered = 0x0123456789ABCDEF
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float64,ordered)))
@test UInt64(0x12) - UInt64(0x3FF) - 52 - 11 == diy_fp.e % UInt64
@test 0x0013456789ABCDEF<< 11 == diy_fp.s

min_double64 = 0x0000000000000001
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float64,min_double64)))
@test -UInt64(0x3FF) - 52 + 1 - 63 == diy_fp.e % UInt64
# This is a denormal so no hidden bit.
@test 0x8000000000000000== diy_fp.s

max_double64 = 0x7fefffffffffffff
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float64,max_double64)))
@test 0x7FE - 0x3FF - 52 - 11 == diy_fp.e % UInt64
@test (0x001fffffffffffff<< 11) == diy_fp.s

min_double64 = 0x0000000000000001
@test Grisu.isdenormal(reinterpret(Float64,min_double64))
float_bits = 0x000FFFFFFFFFFFFF
@test Grisu.isdenormal(reinterpret(Float64,float_bits))
float_bits = 0x0010000000000000
@test !Grisu.isdenormal(reinterpret(Float64,float_bits))

min_float32 = 0x00000001
@test Grisu.isdenormal(reinterpret(Float32,min_float32))
float_bits = 0x007FFFFF
@test Grisu.isdenormal(reinterpret(Float32,float_bits))
float_bits = 0x00800000
@test !Grisu.isdenormal(reinterpret(Float32,float_bits))

diy_fp = Grisu.normalize(Grisu.Float(1.5))
boundary_minus, boundary_plus = Grisu.normalizedbound(1.5)
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# 1.5 does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (1 << 10) == diy_fp.s - boundary_minus.s

diy_fp = Grisu.normalize(Grisu.Float(1.0))
boundary_minus, boundary_plus = Grisu.normalizedbound(1.0)
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# 1.0 does have a significand of the form 2^p (for some p).
# Therefore its lower boundary is twice as close as the upper boundary.
@test boundary_plus.s - diy_fp.s > diy_fp.s - boundary_minus.s
@test (1 << 9) == diy_fp.s - boundary_minus.s
@test (1 << 10) == boundary_plus.s - diy_fp.s

min_double64 = 0x0000000000000001
diy_fp = Grisu.normalize(Grisu.Float(reinterpret(Float64,min_double64)))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float64,min_double64))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# min-value does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
# Denormals have their boundaries much closer.
@test (UInt64(1) << 62) == diy_fp.s - boundary_minus.s

smallest_normal64 = 0x0010000000000000
diy_fp = Grisu.normalize(reinterpret(Float64,smallest_normal64))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float64,smallest_normal64))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# Even though the significand is of the form 2^p (for some p), its boundaries
# are at the same distance. (This is the only exception).
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (1 << 10) == diy_fp.s - boundary_minus.s

largest_denormal64 = 0x000FFFFFFFFFFFFF
diy_fp = Grisu.normalize(reinterpret(Float64,largest_denormal64))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float64,largest_denormal64))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (1 << 11) == diy_fp.s - boundary_minus.s

max_double64 = 0x7fefffffffffffff
diy_fp = Grisu.normalize(reinterpret(Float64,max_double64))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float64,max_double64))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# max-value does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (1 << 10) == diy_fp.s - boundary_minus.s

kOne64 = UInt64(1)
diy_fp  = Grisu.normalize(Grisu.Float(Float32(1.5)))
boundary_minus, boundary_plus = Grisu.normalizedbound(Float32(1.5))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# 1.5 does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
# Normalization shifts the significand by 8 bits. Add 32 bits for the bigger
# data-type, and remove 1 because boundaries are at half a ULP.
@test (kOne64 << 39) == diy_fp.s - boundary_minus.s

diy_fp  = Grisu.normalize(Grisu.Float(Float32(1.0)))
boundary_minus, boundary_plus = Grisu.normalizedbound(Float32(1.0))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# 1.0 does have a significand of the form 2^p (for some p).
# Therefore its lower boundary is twice as close as the upper boundary.
@test boundary_plus.s - diy_fp.s > diy_fp.s - boundary_minus.s
@test (kOne64 << 38) == diy_fp.s - boundary_minus.s
@test (kOne64 << 39) == boundary_plus.s - diy_fp.s

min_float32 = 0x00000001
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float32,min_float32)))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float32,min_float32))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# min-value does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
# Denormals have their boundaries much closer.
@test (kOne64 << 62) == diy_fp.s - boundary_minus.s

smallest_normal32 = 0x00800000
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float32,smallest_normal32)))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float32,smallest_normal32))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# Even though the significand is of the form 2^p (for some p), its boundaries
# are at the same distance. (This is the only exception).
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (kOne64 << 39) == diy_fp.s - boundary_minus.s

largest_denormal32 = 0x007FFFFF
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float32,largest_denormal32)))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float32,largest_denormal32))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (kOne64 << 40) == diy_fp.s - boundary_minus.s

max_float32 = 0x7f7fffff
diy_fp  = Grisu.normalize(Grisu.Float(reinterpret(Float32,max_float32)))
boundary_minus, boundary_plus = Grisu.normalizedbound(reinterpret(Float32,max_float32))
@test diy_fp.e == boundary_minus.e
@test diy_fp.e == boundary_plus.e
# max-value does not have a significand of the form 2^p (for some p).
# Therefore its boundaries are at the same distance.
@test diy_fp.s - boundary_minus.s == boundary_plus.s - diy_fp.s
@test (kOne64 << 39) == diy_fp.s - boundary_minus.s

#fastshortest
min_double = 5e-324
status,len,point = Grisu.fastshortest(min_double, buffer)
@test status
@test "5" == trimrep(buffer)
@test -323 == point
fill!(buffer,0)

max_double = 1.7976931348623157e308
status,len,point = Grisu.fastshortest(max_double, buffer)
@test status
@test "17976931348623157" == trimrep(buffer)
@test 309 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(4294967272.0, buffer)
@test status
@test "4294967272" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(4.1855804968213567e298, buffer)
@test status
@test "4185580496821357" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(5.5626846462680035e-309, buffer)
@test status
@test "5562684646268003" == trimrep(buffer)
@test -308 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(2147483648.0, buffer)
@test status
@test "2147483648" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(3.5844466002796428e+298, buffer)
@test !status  # Not all Grisu.fastshortest variants manage to compute this number.
if status
    @test "35844466002796428" == trimrep(buffer)
    @test 299 == point
    fill!(buffer,0)
end

smallest_normal64 = 0x0010000000000000
v = reinterpret(Float64,smallest_normal64)
status,len,point = Grisu.fastshortest(v,  buffer)
if status
    @test "22250738585072014" == trimrep(buffer)
    @test -307 == point
    fill!(buffer,0)
end

largest_denormal64 = 0x000FFFFFFFFFFFFF
v = reinterpret(Float64,largest_denormal64)
status,len,point = Grisu.fastshortest(v,  buffer)
if status
    @test "2225073858507201" == trimrep(buffer)
    @test -307 == point
    fill!(buffer,0)
end

min_float = Float32(1e-45)
status,len,point = Grisu.fastshortest(min_float, buffer)
@test status
@test "1" == trimrep(buffer)
@test -44 == point
fill!(buffer,0)

max_float = 3.4028234f38 #Float32(3.4028234e38)
status,len,point = Grisu.fastshortest(max_float, buffer)
@test status
@test "34028235" == trimrep(buffer)
@test 39 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(4294967272.0), buffer)
@test status
@test "42949673" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(3.32306998946228968226e+35), buffer)
@test status
@test "332307" == trimrep(buffer)
@test 36 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(1.2341e-41), buffer)
@test status
@test "12341" == trimrep(buffer)
@test -40 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(3.3554432e7), buffer)
@test status
@test "33554432" == trimrep(buffer)
@test 8 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(3.26494756798464e14), buffer)
@test status
@test "32649476" == trimrep(buffer)
@test 15 == point
fill!(buffer,0)

status,len,point = Grisu.fastshortest(Float32(3.91132223637771935344e37), buffer)
if status  # Not all Grisu.fastshortest variants manage to compute this number.
    @test "39113222" == trimrep(buffer)
    @test 38 == point
    fill!(buffer,0)
end

smallest_normal32 = 0x00800000
v = reinterpret(Float32,smallest_normal32)
status,len,point = Grisu.fastshortest(v,  buffer)
if status
    @test "11754944" == trimrep(buffer)
    @test -37 == point
    fill!(buffer,0)
end

largest_denormal32 = 0x007FFFFF
v = reinterpret(Float32,largest_denormal32)
status,len,point = Grisu.fastshortest(v,  buffer)
@test status
@test "11754942" == trimrep(buffer)
@test -37 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(1.0, 3, buffer)
@test status
@test 3 >= len-1
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(1.5, 10, buffer)
if status
    @test 10 >= len-1
    @test "15" == trimrep(buffer)
    @test 1 == point
    fill!(buffer,0)
end

min_double = 5e-324
status,len,point = Grisu.fastprecision(min_double, 5,buffer)
@test status
@test "49407" == trimrep(buffer)
@test -323 == point
fill!(buffer,0)

max_double = 1.7976931348623157e308
status,len,point = Grisu.fastprecision(max_double, 7,buffer)
@test status
@test "1797693" == trimrep(buffer)
@test 309 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(4294967272.0, 14,buffer)
if status
    @test 14 >= len-1
    @test "4294967272" == trimrep(buffer)
    @test 10 == point
    fill!(buffer,0)
end

status,len,point = Grisu.fastprecision(4.1855804968213567e298, 17,buffer)
@test status
@test "41855804968213567" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(5.5626846462680035e-309, 1,buffer)
@test status
@test "6" == trimrep(buffer)
@test -308 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(2147483648.0, 5,buffer)
@test status
@test "21475" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(3.5844466002796428e+298, 10,buffer)
@test status
@test 10 >= len-1
@test "35844466" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)

smallest_normal64 = 0x0010000000000000
v = reinterpret(Float64,smallest_normal64)
status,len,point = Grisu.fastprecision(v, 17, buffer)
@test status
@test "22250738585072014" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)

largest_denormal64 = 0x000FFFFFFFFFFFFF
v = reinterpret(Float64,largest_denormal64)
status,len,point = Grisu.fastprecision(v, 17, buffer)
@test status
@test 20 >= len-1
@test "22250738585072009" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)

v = 3.3161339052167390562200598e-237
status,len,point = Grisu.fastprecision(v, 18, buffer)
@test status
@test "331613390521673906" == trimrep(buffer)
@test -236 == point
fill!(buffer,0)

v = 7.9885183916008099497815232e+191
status,len,point = Grisu.fastprecision(v, 4, buffer)
@test status
@test "7989" == trimrep(buffer)
@test 192 == point
fill!(buffer,0)

#fastfixedtoa
status,len,point = Grisu.fastfixedtoa(1.0, 0,1, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.0, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.0, 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0xFFFFFFFF, 0,5, buffer)
@test "4294967295" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(4294967296.0, 0,5, buffer)
@test "4294967296" == unsafe_string(pointer(buffer)) #todo
@test 10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e21, 0,5, buffer)
@test "1" == unsafe_string(pointer(buffer)) #todo extra '0's
@test 22 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(999999999999999868928.00, 0,2, buffer)
@test "999999999999999868928" == unsafe_string(pointer(buffer)) #todo extra '0'
@test 21 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(6.9999999999999989514240000e+21, 0,5, buffer)
@test "6999999999999998951424" == unsafe_string(pointer(buffer)) #todo short several '9's
@test 22 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.5, 0,5, buffer)
@test "15" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.55, 0,5, buffer)
@test "155" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.55, 0,1, buffer)
@test "16" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.00000001, 0,15, buffer)
@test "100000001" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.1, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 0 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.01, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.001, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0001, 0,10, buffer) #todo
@test "1" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00001, 0,10, buffer) #todo
@test "1" == unsafe_string(pointer(buffer))
@test -4 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000001, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000001, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -6 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000001, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -7 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000001, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -8 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000001, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -9 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000001, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000001, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -11 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000001, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -12 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000000001, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -13 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -14 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -15 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -16 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -17 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -18 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000000000000001, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -19 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.10000000004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 0 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.01000000004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00100000004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00010000004, 0,10, buffer) #todo
@test "1" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00001000004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -4 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000100004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000010004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -6 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000001004, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -7 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000104, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -8 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000001000004, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -9 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000100004, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000010004, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -11 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000001004, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -12 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000000104, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -13 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000001000004, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -14 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000100004, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -15 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000010004, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -16 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000001004, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -17 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000000104, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -18 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000000014, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -19 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.10000000006, 0,10, buffer)
@test "1000000001" == unsafe_string(pointer(buffer))
@test 0 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.01000000006, 0,10, buffer)
@test "100000001" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00100000006, 0,10, buffer)
@test "10000001" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00010000006, 0,10, buffer)
@test "1000001" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00001000006, 0,10, buffer)
@test "100001" == unsafe_string(pointer(buffer))
@test -4 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000100006, 0,10, buffer)
@test "10001" == unsafe_string(pointer(buffer))
@test -5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000010006, 0,10, buffer)
@test "1001" == unsafe_string(pointer(buffer))
@test -6 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000001006, 0,10, buffer)
@test "101" == unsafe_string(pointer(buffer))
@test -7 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000000106, 0,10, buffer)
@test "11" == unsafe_string(pointer(buffer))
@test -8 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000001000006, 0,15, buffer)
@test "100001" == unsafe_string(pointer(buffer))
@test -9 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000100006, 0,15, buffer)
@test "10001" == unsafe_string(pointer(buffer))
@test -10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000010006, 0,15, buffer)
@test "1001" == unsafe_string(pointer(buffer))
@test -11 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000001006, 0,15, buffer)
@test "101" == unsafe_string(pointer(buffer))
@test -12 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000000000000106, 0,15, buffer)
@test "11" == unsafe_string(pointer(buffer))
@test -13 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000001000006, 0,20, buffer)
@test "100001" == unsafe_string(pointer(buffer))
@test -14 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000100006, 0,20, buffer)
@test "10001" == unsafe_string(pointer(buffer))
@test -15 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000010006, 0,20, buffer)
@test "1001" == unsafe_string(pointer(buffer))
@test -16 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000001006, 0,20, buffer)
@test "101" == unsafe_string(pointer(buffer))
@test -17 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000000106, 0,20, buffer)
@test "11" == unsafe_string(pointer(buffer))
@test -18 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000000000000000016, 0,20, buffer)
@test "2" == unsafe_string(pointer(buffer))
@test -19 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.6, 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.96, 0,1, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.996, 0,2, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.9996, 0,3, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.99996, 0,4, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.999996, 0,5, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.9999996, 0,6, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.99999996, 0,7, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.999999996, 0,8, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.9999999996, 0,9, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.99999999996, 0,10, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.999999999996, 0,11, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.9999999999996, 0,12, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.99999999999996, 0,13, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.999999999999996, 0,14, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.9999999999999996, 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00999999999999996, 0,16, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000999999999999996, 0,17, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.0000999999999999996, 0,18, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.00000999999999999996, 0,19, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -4 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.000000999999999999996, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(323423.234234, 0,10, buffer)
@test "323423234234" == unsafe_string(pointer(buffer))
@test 6 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(12345678.901234, 0,4, buffer)
@test "123456789012" == unsafe_string(pointer(buffer))
@test 8 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(98765.432109, 0,5, buffer)
@test "9876543211" == unsafe_string(pointer(buffer))
@test 5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(42, 0,20, buffer)
@test "42" == unsafe_string(pointer(buffer))
@test 2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(0.5, 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-23, 0,10, buffer)
@test "" == unsafe_string(pointer(buffer))
@test -10 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-123, 0,2, buffer)
@test "" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-123, 0,0, buffer)
@test "" == unsafe_string(pointer(buffer))
@test 0 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-23, 0,20, buffer)
@test "" == unsafe_string(pointer(buffer))
@test -20 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-21, 0,20, buffer)
@test "" == unsafe_string(pointer(buffer))
@test -20 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1e-22, 0,20, buffer)
@test "" == unsafe_string(pointer(buffer))
@test -20 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(6e-21, 0,20, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -19 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(9.1193616301674545152000000e+19, 0,0,buffer)
@test "91193616301674545152" == unsafe_string(pointer(buffer))
@test 20 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(4.8184662102767651659096515e-04, 0,19,buffer)
@test "4818466210276765" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1.9023164229540652612705182e-23, 0,8,buffer)
@test "" == unsafe_string(pointer(buffer))
@test -8 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(1000000000000000128.0, 0,0,buffer)
@test "1000000000000000128" == unsafe_string(pointer(buffer))
@test 19 == point
fill!(buffer,0)

#bignumdtoa
status,len,point = Grisu.bignumdtoa(1.0, Grisu.SHORTEST, 0, buffer,bignums)
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(1.0, Grisu.FIXED, 3, buffer,bignums)
@test 3 >= len - 1 - point
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(1.0, Grisu.PRECISION, 3, buffer,bignums)
@test 3 >= len - 1
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(1.5, Grisu.SHORTEST, 0, buffer,bignums)
@test "15" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(1.5, Grisu.FIXED, 10, buffer,bignums)
@test 10 >= len - 1 - point
@test "15" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(1.5, Grisu.PRECISION, 10, buffer,bignums)
@test 10 >= len - 1
@test "15" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

min_double = 5e-324
status,len,point = Grisu.bignumdtoa(min_double, Grisu.SHORTEST, 0, buffer,bignums)
@test "5" == trimrep(buffer)
@test -323 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(min_double, Grisu.FIXED, 5, buffer,bignums)
@test 5 >= len - 1 - point
@test "" == trimrep(buffer)

status,len,point = Grisu.bignumdtoa(min_double, Grisu.PRECISION, 5, buffer,bignums)
@test 5 >= len - 1
@test "49407" == trimrep(buffer)
@test -323 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

max_double = 1.7976931348623157e308
status,len,point = Grisu.bignumdtoa(max_double, Grisu.SHORTEST, 0, buffer,bignums)
@test "17976931348623157" == trimrep(buffer)
@test 309 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(max_double, Grisu.PRECISION, 7, buffer,bignums)
@test 7 >= len - 1
@test "1797693" == trimrep(buffer)
@test 309 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4294967272.0, Grisu.SHORTEST, 0, buffer,bignums)
@test "4294967272" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4294967272.0, Grisu.FIXED, 5, buffer,bignums)
@test "429496727200000" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4294967272.0, Grisu.PRECISION, 14, buffer,bignums)
@test 14 >= len - 1
@test "4294967272" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4.1855804968213567e298, Grisu.SHORTEST, 0,buffer,bignums)
@test "4185580496821357" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4.1855804968213567e298, Grisu.PRECISION, 20,buffer,bignums)
@test 20 >= len - 1
@test "41855804968213567225" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(5.5626846462680035e-309, Grisu.SHORTEST, 0, buffer,bignums)
@test "5562684646268003" == trimrep(buffer)
@test -308 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(5.5626846462680035e-309, Grisu.PRECISION, 1, buffer,bignums)
@test 1 >= len - 1
@test "6" == trimrep(buffer)
@test -308 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(2147483648.0, Grisu.SHORTEST, 0, buffer,bignums)
@test "2147483648" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(2147483648.0, Grisu.FIXED, 2, buffer,bignums)
@test 2 >= len - 1 - point
@test "2147483648" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(2147483648.0, Grisu.PRECISION, 5, buffer,bignums)
@test 5 >= len - 1
@test "21475" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(3.5844466002796428e+298, Grisu.SHORTEST, 0, buffer,bignums)
@test "35844466002796428" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(3.5844466002796428e+298, Grisu.PRECISION, 10, buffer,bignums)
@test 10 >= len - 1
@test "35844466" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = reinterpret(Float64,0x0010000000000000)
status,len,point = Grisu.bignumdtoa(v, Grisu.SHORTEST, 0, buffer,bignums)
@test "22250738585072014" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(v, Grisu.PRECISION, 20, buffer,bignums)
@test 20 >= len - 1
@test "22250738585072013831" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = reinterpret(Float64,0x000FFFFFFFFFFFFF)
status,len,point = Grisu.bignumdtoa(v, Grisu.SHORTEST, 0, buffer,bignums)
@test "2225073858507201" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(v, Grisu.PRECISION, 20, buffer,bignums)
@test 20 >= len - 1
@test "2225073858507200889" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(4128420500802942e-24, Grisu.SHORTEST, 0, buffer,bignums)
@test "4128420500802942" == trimrep(buffer)
@test -8 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = 3.9292015898194142585311918e-10
status,len,point = Grisu.bignumdtoa(v, Grisu.SHORTEST, 0, buffer,bignums)
@test "39292015898194143" == trimrep(buffer)

v = 4194304.0
status,len,point = Grisu.bignumdtoa(v, Grisu.FIXED, 5, buffer,bignums)
@test 5 >= len - 1 - point
@test "4194304" == trimrep(buffer)

v = 3.3161339052167390562200598e-237
status,len,point = Grisu.bignumdtoa(v, Grisu.PRECISION, 19, buffer,bignums)
@test 19 >= len - 1
@test "3316133905216739056" == trimrep(buffer)
@test -236 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = 7.9885183916008099497815232e+191
status,len,point = Grisu.bignumdtoa(v, Grisu.PRECISION, 4, buffer,bignums)
@test 4 >= len - 1
@test "7989" == trimrep(buffer)
@test 192 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = 1.0000000000000012800000000e+17
status,len,point = Grisu.bignumdtoa(v, Grisu.FIXED, 1, buffer,bignums)
@test 1 >= len - 1 - point
@test "100000000000000128" == trimrep(buffer)
@test 18 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

min_float = Float32(1e-45)
status,len,point = Grisu.bignumdtoa(min_float, Grisu.SHORTEST, 0, buffer,bignums)
@test "1" == trimrep(buffer)
@test -44 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

max_float = Float32(3.4028234e38)
status,len,point = Grisu.bignumdtoa(max_float, Grisu.SHORTEST, 0, buffer,bignums)
@test "34028235" == trimrep(buffer)
@test 39 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(4294967272.0), Grisu.SHORTEST, 0, buffer,bignums)
@test "42949673" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(3.32306998946228968226e+35), Grisu.SHORTEST, 0, buffer,bignums)
@test "332307" == trimrep(buffer)
@test 36 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(1.2341e-41), Grisu.SHORTEST, 0, buffer,bignums)
@test "12341" == trimrep(buffer)
@test -40 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(3.3554432e7), Grisu.SHORTEST, 0, buffer,bignums)
@test "33554432" == trimrep(buffer)
@test 8 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(3.26494756798464e14), Grisu.SHORTEST, 0, buffer,bignums)
@test "32649476" == trimrep(buffer)
@test 15 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

status,len,point = Grisu.bignumdtoa(Float32(3.91132223637771935344e37), Grisu.SHORTEST, 0, buffer,bignums)
@test "39113222" == trimrep(buffer)
@test 38 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = reinterpret(Float32,0x00800000)
status,len,point = Grisu.bignumdtoa(v, Grisu.SHORTEST, 0, buffer,bignums)
@test "11754944" == trimrep(buffer)
@test -37 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

v = reinterpret(Float32,0x007FFFFF)
status,len,point = Grisu.bignumdtoa(v, Grisu.SHORTEST, 0, buffer,bignums)
@test "11754942" == trimrep(buffer)
@test -37 == point
fill!(buffer,0)
map(x->Grisu.Bignums.zero!(x),bignums)

#Float16
min_double = realmin(Float16)
status,len,point = Grisu.fastshortest(min_double,buffer)
@test status
@test "6104" == trimrep(buffer)
@test -4 == point
fill!(buffer,0)

max_double = realmax(Float16)
status,len,point = Grisu.fastshortest(max_double,buffer)
@test status
@test "655" == trimrep(buffer)
@test 5 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(Float16(1.0), 3, buffer)
@test status
@test 3 >= len-1
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastprecision(Float16(1.5), 10, buffer)
if status
    @test 10 >= len-1
    @test "15" == trimrep(buffer)
    @test 1 == point
    fill!(buffer,0)
end

status,len,point = Grisu.fastfixedtoa(Float16(1.0), 0,1, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.0), 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.0), 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.5), 0,5, buffer)
@test "15" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.55), 0,5, buffer)
@test "15498" == unsafe_string(pointer(buffer)) #todo
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.55), 0,1, buffer)
@test "15" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(1.00000001), 0,15, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.1), 0,10, buffer)
@test "999755859" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.01), 0,10, buffer)
@test "100021362" == unsafe_string(pointer(buffer))
@test -1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.001), 0,10, buffer)
@test "10004044" == unsafe_string(pointer(buffer))
@test -2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.0001), 0,10, buffer) #todo
@test "1000166" == unsafe_string(pointer(buffer))
@test -3 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.00001), 0,10, buffer) #todo
@test "100136" == unsafe_string(pointer(buffer))
@test -4 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.000001), 0,10, buffer)
@test "10133" == unsafe_string(pointer(buffer))
@test -5 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.0000001), 0,10, buffer)
@test "1192" == unsafe_string(pointer(buffer))
@test -6 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.6), 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.96), 0,1, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.996), 0,2, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.9996), 0,3, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.99996), 0,4, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.999996), 0,5, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.9999996), 0,6, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.99999996), 0,7, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(42), 0,20, buffer)
@test "42" == unsafe_string(pointer(buffer))
@test 2 == point
fill!(buffer,0)

status,len,point = Grisu.fastfixedtoa(Float16(0.5), 0,0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

#dtoa
len,point,neg = Grisu.grisu(0.0, Grisu.SHORTEST, 0, buffer)
@test "0" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(Float32(0.0), Grisu.SHORTEST, 0, buffer)
@test "0" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(0.0, Grisu.FIXED, 2, buffer)
@test 1 >= len-1
@test "0" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(0.0, Grisu.PRECISION, 3, buffer)
@test 1 >= len-1
@test "0" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.0, Grisu.SHORTEST, 0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(Float32(1.0), Grisu.SHORTEST, 0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.0, Grisu.FIXED, 3, buffer)
@test 3 >= len-1-point
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.0, Grisu.PRECISION, 3, buffer)
@test 3 >= len-1
@test "1" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.5, Grisu.SHORTEST, 0, buffer)
@test "15" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(Float32(1.5), Grisu.SHORTEST, 0, buffer)
@test "15" == unsafe_string(pointer(buffer))
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.5, Grisu.FIXED, 10, buffer)
@test 10 >= len-1-point
@test "15" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(1.5, Grisu.PRECISION, 10, buffer)
@test 10 >= len-1
@test "15" == trimrep(buffer)
@test 1 == point
fill!(buffer,0)

min_double = 5e-324
len,point,neg = Grisu.grisu(min_double, Grisu.SHORTEST, 0, buffer)
@test "5" == unsafe_string(pointer(buffer))
@test -323 == point
fill!(buffer,0)

min_float = 1e-45
len,point,neg = Grisu.grisu(Float32(min_float), Grisu.SHORTEST, 0, buffer)
@test "1" == unsafe_string(pointer(buffer))
@test -44 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(min_double, Grisu.FIXED, 5, buffer)
@test 5 >= len-1-point
@test "" == trimrep(buffer)
@test -5 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(min_double, Grisu.PRECISION, 5, buffer)
@test 5 >= len-1
@test "49407" == trimrep(buffer)
@test -323 == point
fill!(buffer,0)

max_double = 1.7976931348623157e308
len,point,neg = Grisu.grisu(max_double, Grisu.SHORTEST, 0, buffer)
@test "17976931348623157" == unsafe_string(pointer(buffer))
@test 309 == point
fill!(buffer,0)

max_float = 3.4028234e38
len,point,neg = Grisu.grisu(Float32(max_float), Grisu.SHORTEST, 0, buffer)
@test "34028235" == unsafe_string(pointer(buffer))
@test 39 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(max_double, Grisu.PRECISION, 7, buffer)
@test 7 >= len-1
@test "1797693" == trimrep(buffer)
@test 309 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4294967272.0, Grisu.SHORTEST, 0, buffer)
@test "4294967272" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(Float32(4294967272.0), Grisu.SHORTEST, 0, buffer)
@test "42949673" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4294967272.0, Grisu.FIXED, 5, buffer)
@test 5 >= len-1-point
@test "4294967272" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4294967272.0, Grisu.PRECISION, 14, buffer)
@test 14 >= len-1
@test "4294967272" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4.1855804968213567e298, Grisu.SHORTEST, 0, buffer)
@test "4185580496821357" == unsafe_string(pointer(buffer))
@test 299 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4.1855804968213567e298, Grisu.PRECISION, 20, buffer)
@test 20 >= len-1
@test "41855804968213567225" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(5.5626846462680035e-309, Grisu.SHORTEST, 0, buffer)
@test "5562684646268003" == unsafe_string(pointer(buffer))
@test -308 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(5.5626846462680035e-309, Grisu.PRECISION, 1, buffer)
@test 1 >= len-1
@test "6" == trimrep(buffer)
@test -308 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(-2147483648.0, Grisu.SHORTEST, 0, buffer)
@test 1 == neg
@test "2147483648" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(Float32(-2147483648.), Grisu.SHORTEST, 0, buffer)
@test 1 == neg
@test "21474836" == unsafe_string(pointer(buffer))
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(-2147483648.0, Grisu.FIXED, 2, buffer)
@test 2 >= len-1-point
@test "2147483648" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(-2147483648.0, Grisu.PRECISION, 5, buffer)
@test 5 >= len-1
@test "21475" == trimrep(buffer)
@test 10 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(-3.5844466002796428e+298, Grisu.SHORTEST, 0, buffer)
@test 1 == neg
@test "35844466002796428" == unsafe_string(pointer(buffer))
@test 299 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(-3.5844466002796428e+298, Grisu.PRECISION, 10, buffer)
@test 1 == neg
@test 10 >= len-1
@test "35844466" == trimrep(buffer)
@test 299 == point
fill!(buffer,0)

v = reinterpret(Float64,0x0010000000000000)
len,point,neg = Grisu.grisu(v, Grisu.SHORTEST, 0, buffer)
@test "22250738585072014" == unsafe_string(pointer(buffer))
@test -307 == point
fill!(buffer,0)

f = reinterpret(Float32,0x00800000)
len,point,neg = Grisu.grisu(f, Grisu.SHORTEST, 0, buffer)
@test "11754944" == unsafe_string(pointer(buffer))
@test -37 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(v, Grisu.PRECISION, 20, buffer)
@test 20 >= len-1
@test "22250738585072013831" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)

v = reinterpret(Float64,0x000FFFFFFFFFFFFF)
len,point,neg = Grisu.grisu(v, Grisu.SHORTEST, 0, buffer)
@test "2225073858507201" == unsafe_string(pointer(buffer))
@test -307 == point
fill!(buffer,0)

f = reinterpret(Float32,0x007FFFFF)
len,point,neg = Grisu.grisu(f, Grisu.SHORTEST, 0, buffer)
@test "11754942" == unsafe_string(pointer(buffer))
@test -37 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(v, Grisu.PRECISION, 20, buffer)
@test 20 >= len-1
@test "2225073858507200889" == trimrep(buffer)
@test -307 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(4128420500802942e-24, Grisu.SHORTEST, 0, buffer)
@test 0 == neg
@test "4128420500802942" == unsafe_string(pointer(buffer))
@test -8 == point
fill!(buffer,0)

v = -3.9292015898194142585311918e-10
len,point,neg = Grisu.grisu(v, Grisu.SHORTEST, 0, buffer)
@test "39292015898194143" == unsafe_string(pointer(buffer))
fill!(buffer,0)

f = Float32(-3.9292015898194142585311918e-10)
len,point,neg = Grisu.grisu(f, Grisu.SHORTEST, 0, buffer)
@test "39292017" == unsafe_string(pointer(buffer))
fill!(buffer,0)

v = 4194304.0
len,point,neg = Grisu.grisu(v, Grisu.FIXED, 5, buffer)
@test 5 >= len-1-point
@test "4194304" == trimrep(buffer)
fill!(buffer,0)

v = 3.3161339052167390562200598e-237
len,point,neg = Grisu.grisu(v, Grisu.PRECISION, 19, buffer)
@test 19 >= len-1
@test "3316133905216739056" == trimrep(buffer)
@test -236 == point
fill!(buffer,0)

len,point,neg = Grisu.grisu(0.0, Grisu.SHORTEST, 0, buffer)
@test !neg

len,point,neg = Grisu.grisu(-0.0, Grisu.SHORTEST, 0, buffer)
@test neg

len,point,neg = Grisu.grisu(1.0, Grisu.SHORTEST, 0, buffer)
@test !neg

len,point,neg = Grisu.grisu(-1.0, Grisu.SHORTEST, 0, buffer)
@test neg

len,point,neg = Grisu.grisu(Float32(0.0), Grisu.SHORTEST, 0, buffer)
@test !neg

len,point,neg = Grisu.grisu(-Float32(0.0), Grisu.SHORTEST, 0, buffer)
@test neg

len,point,neg = Grisu.grisu(Float32(1.0), Grisu.SHORTEST, 0, buffer)
@test !neg

len,point,neg = Grisu.grisu(-Float32(1.0), Grisu.SHORTEST, 0, buffer)
@test neg

len,point,neg = Grisu.grisu(0.0, Grisu.PRECISION, 1, buffer)
@test !neg

len,point,neg = Grisu.grisu(-0.0, Grisu.PRECISION, 1, buffer)
@test neg

len,point,neg = Grisu.grisu(1.0, Grisu.PRECISION, 1, buffer)
@test !neg

len,point,neg = Grisu.grisu(-1.0, Grisu.PRECISION, 1, buffer)
@test neg

len,point,neg = Grisu.grisu(0.0, Grisu.FIXED, 1, buffer)
@test !neg

len,point,neg = Grisu.grisu(-0.0, Grisu.FIXED, 1, buffer)
@test neg

len,point,neg = Grisu.grisu(1.0, Grisu.FIXED, 1, buffer)
@test !neg

len,point,neg = Grisu.grisu(-1.0, Grisu.FIXED, 1, buffer)
@test neg

len,point,neg = Grisu.grisu(0.0, Grisu.PRECISION, 0, buffer)
@test 0 >= len-1
@test "" == unsafe_string(pointer(buffer))
@test !neg

len,point,neg = Grisu.grisu(1.0, Grisu.PRECISION, 0, buffer)
@test 0 >= len-1
@test "" == unsafe_string(pointer(buffer))
@test !neg

len,point,neg = Grisu.grisu(0.0, Grisu.FIXED, 0, buffer)
@test 1 >= len-1
@test "0" == unsafe_string(pointer(buffer))
@test !neg

len,point,neg = Grisu.grisu(1.0, Grisu.FIXED, 0, buffer)
@test 1 >= len-1
@test "1" == unsafe_string(pointer(buffer))
@test !neg

max_stars_repo_name: caodi/julia

max_issues_repo_name: caodi/julia

max_forks_repo_name: caodi/julia