# c_stores.jl — AUTO-GENERATED by scripts/generate_stores.jl — do not edit.
#
# 34 solvers × 4 precisions = 136 typed workspace stores.
# Each store is a Dict{Ptr{Cvoid}, <ConcreteWorkspaceType>} that acts as a
# GC root while keeping types fully concrete for --trim=safe.
#
# Re-generate with:
#   julia --startup-file=no --project=<root> scripts/generate_stores.jl

# ---------------------------------------------------------------------------
# Typed workspace stores
# ---------------------------------------------------------------------------

const store_cg_f32 = Dict{Ptr{Cvoid}, Krylov.CgWorkspace{Float32, Float32, Vector{Float32}}}()
const store_cg_f64 = Dict{Ptr{Cvoid}, Krylov.CgWorkspace{Float64, Float64, Vector{Float64}}}()
const store_cg_cf32 = Dict{Ptr{Cvoid}, Krylov.CgWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_cg_cf64 = Dict{Ptr{Cvoid}, Krylov.CgWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_cr_f32 = Dict{Ptr{Cvoid}, Krylov.CrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_cr_f64 = Dict{Ptr{Cvoid}, Krylov.CrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_cr_cf32 = Dict{Ptr{Cvoid}, Krylov.CrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_cr_cf64 = Dict{Ptr{Cvoid}, Krylov.CrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_symmlq_f32 = Dict{Ptr{Cvoid}, Krylov.SymmlqWorkspace{Float32, Float32, Vector{Float32}}}()
const store_symmlq_f64 = Dict{Ptr{Cvoid}, Krylov.SymmlqWorkspace{Float64, Float64, Vector{Float64}}}()
const store_symmlq_cf32 = Dict{Ptr{Cvoid}, Krylov.SymmlqWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_symmlq_cf64 = Dict{Ptr{Cvoid}, Krylov.SymmlqWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_minres_f32 = Dict{Ptr{Cvoid}, Krylov.MinresWorkspace{Float32, Float32, Vector{Float32}}}()
const store_minres_f64 = Dict{Ptr{Cvoid}, Krylov.MinresWorkspace{Float64, Float64, Vector{Float64}}}()
const store_minres_cf32 = Dict{Ptr{Cvoid}, Krylov.MinresWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_minres_cf64 = Dict{Ptr{Cvoid}, Krylov.MinresWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_minres_qlp_f32 = Dict{Ptr{Cvoid}, Krylov.MinresQlpWorkspace{Float32, Float32, Vector{Float32}}}()
const store_minres_qlp_f64 = Dict{Ptr{Cvoid}, Krylov.MinresQlpWorkspace{Float64, Float64, Vector{Float64}}}()
const store_minres_qlp_cf32 = Dict{Ptr{Cvoid}, Krylov.MinresQlpWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_minres_qlp_cf64 = Dict{Ptr{Cvoid}, Krylov.MinresQlpWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_diom_f32 = Dict{Ptr{Cvoid}, Krylov.DiomWorkspace{Float32, Float32, Vector{Float32}}}()
const store_diom_f64 = Dict{Ptr{Cvoid}, Krylov.DiomWorkspace{Float64, Float64, Vector{Float64}}}()
const store_diom_cf32 = Dict{Ptr{Cvoid}, Krylov.DiomWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_diom_cf64 = Dict{Ptr{Cvoid}, Krylov.DiomWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_dqgmres_f32 = Dict{Ptr{Cvoid}, Krylov.DqgmresWorkspace{Float32, Float32, Vector{Float32}}}()
const store_dqgmres_f64 = Dict{Ptr{Cvoid}, Krylov.DqgmresWorkspace{Float64, Float64, Vector{Float64}}}()
const store_dqgmres_cf32 = Dict{Ptr{Cvoid}, Krylov.DqgmresWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_dqgmres_cf64 = Dict{Ptr{Cvoid}, Krylov.DqgmresWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_fom_f32 = Dict{Ptr{Cvoid}, Krylov.FomWorkspace{Float32, Float32, Vector{Float32}}}()
const store_fom_f64 = Dict{Ptr{Cvoid}, Krylov.FomWorkspace{Float64, Float64, Vector{Float64}}}()
const store_fom_cf32 = Dict{Ptr{Cvoid}, Krylov.FomWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_fom_cf64 = Dict{Ptr{Cvoid}, Krylov.FomWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_gmres_f32 = Dict{Ptr{Cvoid}, Krylov.GmresWorkspace{Float32, Float32, Vector{Float32}}}()
const store_gmres_f64 = Dict{Ptr{Cvoid}, Krylov.GmresWorkspace{Float64, Float64, Vector{Float64}}}()
const store_gmres_cf32 = Dict{Ptr{Cvoid}, Krylov.GmresWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_gmres_cf64 = Dict{Ptr{Cvoid}, Krylov.GmresWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_fgmres_f32 = Dict{Ptr{Cvoid}, Krylov.FgmresWorkspace{Float32, Float32, Vector{Float32}}}()
const store_fgmres_f64 = Dict{Ptr{Cvoid}, Krylov.FgmresWorkspace{Float64, Float64, Vector{Float64}}}()
const store_fgmres_cf32 = Dict{Ptr{Cvoid}, Krylov.FgmresWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_fgmres_cf64 = Dict{Ptr{Cvoid}, Krylov.FgmresWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_bicgstab_f32 = Dict{Ptr{Cvoid}, Krylov.BicgstabWorkspace{Float32, Float32, Vector{Float32}}}()
const store_bicgstab_f64 = Dict{Ptr{Cvoid}, Krylov.BicgstabWorkspace{Float64, Float64, Vector{Float64}}}()
const store_bicgstab_cf32 = Dict{Ptr{Cvoid}, Krylov.BicgstabWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_bicgstab_cf64 = Dict{Ptr{Cvoid}, Krylov.BicgstabWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_cgs_f32 = Dict{Ptr{Cvoid}, Krylov.CgsWorkspace{Float32, Float32, Vector{Float32}}}()
const store_cgs_f64 = Dict{Ptr{Cvoid}, Krylov.CgsWorkspace{Float64, Float64, Vector{Float64}}}()
const store_cgs_cf32 = Dict{Ptr{Cvoid}, Krylov.CgsWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_cgs_cf64 = Dict{Ptr{Cvoid}, Krylov.CgsWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_bilq_f32 = Dict{Ptr{Cvoid}, Krylov.BilqWorkspace{Float32, Float32, Vector{Float32}}}()
const store_bilq_f64 = Dict{Ptr{Cvoid}, Krylov.BilqWorkspace{Float64, Float64, Vector{Float64}}}()
const store_bilq_cf32 = Dict{Ptr{Cvoid}, Krylov.BilqWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_bilq_cf64 = Dict{Ptr{Cvoid}, Krylov.BilqWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_qmr_f32 = Dict{Ptr{Cvoid}, Krylov.QmrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_qmr_f64 = Dict{Ptr{Cvoid}, Krylov.QmrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_qmr_cf32 = Dict{Ptr{Cvoid}, Krylov.QmrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_qmr_cf64 = Dict{Ptr{Cvoid}, Krylov.QmrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_usymlq_f32 = Dict{Ptr{Cvoid}, Krylov.UsymlqWorkspace{Float32, Float32, Vector{Float32}}}()
const store_usymlq_f64 = Dict{Ptr{Cvoid}, Krylov.UsymlqWorkspace{Float64, Float64, Vector{Float64}}}()
const store_usymlq_cf32 = Dict{Ptr{Cvoid}, Krylov.UsymlqWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_usymlq_cf64 = Dict{Ptr{Cvoid}, Krylov.UsymlqWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_usymqr_f32 = Dict{Ptr{Cvoid}, Krylov.UsymqrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_usymqr_f64 = Dict{Ptr{Cvoid}, Krylov.UsymqrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_usymqr_cf32 = Dict{Ptr{Cvoid}, Krylov.UsymqrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_usymqr_cf64 = Dict{Ptr{Cvoid}, Krylov.UsymqrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_tricg_f32 = Dict{Ptr{Cvoid}, Krylov.TricgWorkspace{Float32, Float32, Vector{Float32}}}()
const store_tricg_f64 = Dict{Ptr{Cvoid}, Krylov.TricgWorkspace{Float64, Float64, Vector{Float64}}}()
const store_tricg_cf32 = Dict{Ptr{Cvoid}, Krylov.TricgWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_tricg_cf64 = Dict{Ptr{Cvoid}, Krylov.TricgWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_trimr_f32 = Dict{Ptr{Cvoid}, Krylov.TrimrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_trimr_f64 = Dict{Ptr{Cvoid}, Krylov.TrimrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_trimr_cf32 = Dict{Ptr{Cvoid}, Krylov.TrimrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_trimr_cf64 = Dict{Ptr{Cvoid}, Krylov.TrimrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_trilqr_f32 = Dict{Ptr{Cvoid}, Krylov.TrilqrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_trilqr_f64 = Dict{Ptr{Cvoid}, Krylov.TrilqrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_trilqr_cf32 = Dict{Ptr{Cvoid}, Krylov.TrilqrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_trilqr_cf64 = Dict{Ptr{Cvoid}, Krylov.TrilqrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_bilqr_f32 = Dict{Ptr{Cvoid}, Krylov.BilqrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_bilqr_f64 = Dict{Ptr{Cvoid}, Krylov.BilqrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_bilqr_cf32 = Dict{Ptr{Cvoid}, Krylov.BilqrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_bilqr_cf64 = Dict{Ptr{Cvoid}, Krylov.BilqrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_lslq_f32 = Dict{Ptr{Cvoid}, Krylov.LslqWorkspace{Float32, Float32, Vector{Float32}}}()
const store_lslq_f64 = Dict{Ptr{Cvoid}, Krylov.LslqWorkspace{Float64, Float64, Vector{Float64}}}()
const store_lslq_cf32 = Dict{Ptr{Cvoid}, Krylov.LslqWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_lslq_cf64 = Dict{Ptr{Cvoid}, Krylov.LslqWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_lsqr_f32 = Dict{Ptr{Cvoid}, Krylov.LsqrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_lsqr_f64 = Dict{Ptr{Cvoid}, Krylov.LsqrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_lsqr_cf32 = Dict{Ptr{Cvoid}, Krylov.LsqrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_lsqr_cf64 = Dict{Ptr{Cvoid}, Krylov.LsqrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_lsmr_f32 = Dict{Ptr{Cvoid}, Krylov.LsmrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_lsmr_f64 = Dict{Ptr{Cvoid}, Krylov.LsmrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_lsmr_cf32 = Dict{Ptr{Cvoid}, Krylov.LsmrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_lsmr_cf64 = Dict{Ptr{Cvoid}, Krylov.LsmrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_usymlqr_f32 = Dict{Ptr{Cvoid}, Krylov.UsymlqrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_usymlqr_f64 = Dict{Ptr{Cvoid}, Krylov.UsymlqrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_usymlqr_cf32 = Dict{Ptr{Cvoid}, Krylov.UsymlqrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_usymlqr_cf64 = Dict{Ptr{Cvoid}, Krylov.UsymlqrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_cgls_f32 = Dict{Ptr{Cvoid}, Krylov.CglsWorkspace{Float32, Float32, Vector{Float32}}}()
const store_cgls_f64 = Dict{Ptr{Cvoid}, Krylov.CglsWorkspace{Float64, Float64, Vector{Float64}}}()
const store_cgls_cf32 = Dict{Ptr{Cvoid}, Krylov.CglsWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_cgls_cf64 = Dict{Ptr{Cvoid}, Krylov.CglsWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_crls_f32 = Dict{Ptr{Cvoid}, Krylov.CrlsWorkspace{Float32, Float32, Vector{Float32}}}()
const store_crls_f64 = Dict{Ptr{Cvoid}, Krylov.CrlsWorkspace{Float64, Float64, Vector{Float64}}}()
const store_crls_cf32 = Dict{Ptr{Cvoid}, Krylov.CrlsWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_crls_cf64 = Dict{Ptr{Cvoid}, Krylov.CrlsWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_cgne_f32 = Dict{Ptr{Cvoid}, Krylov.CgneWorkspace{Float32, Float32, Vector{Float32}}}()
const store_cgne_f64 = Dict{Ptr{Cvoid}, Krylov.CgneWorkspace{Float64, Float64, Vector{Float64}}}()
const store_cgne_cf32 = Dict{Ptr{Cvoid}, Krylov.CgneWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_cgne_cf64 = Dict{Ptr{Cvoid}, Krylov.CgneWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_crmr_f32 = Dict{Ptr{Cvoid}, Krylov.CrmrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_crmr_f64 = Dict{Ptr{Cvoid}, Krylov.CrmrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_crmr_cf32 = Dict{Ptr{Cvoid}, Krylov.CrmrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_crmr_cf64 = Dict{Ptr{Cvoid}, Krylov.CrmrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_craig_f32 = Dict{Ptr{Cvoid}, Krylov.CraigWorkspace{Float32, Float32, Vector{Float32}}}()
const store_craig_f64 = Dict{Ptr{Cvoid}, Krylov.CraigWorkspace{Float64, Float64, Vector{Float64}}}()
const store_craig_cf32 = Dict{Ptr{Cvoid}, Krylov.CraigWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_craig_cf64 = Dict{Ptr{Cvoid}, Krylov.CraigWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_craigmr_f32 = Dict{Ptr{Cvoid}, Krylov.CraigmrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_craigmr_f64 = Dict{Ptr{Cvoid}, Krylov.CraigmrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_craigmr_cf32 = Dict{Ptr{Cvoid}, Krylov.CraigmrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_craigmr_cf64 = Dict{Ptr{Cvoid}, Krylov.CraigmrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_lnlq_f32 = Dict{Ptr{Cvoid}, Krylov.LnlqWorkspace{Float32, Float32, Vector{Float32}}}()
const store_lnlq_f64 = Dict{Ptr{Cvoid}, Krylov.LnlqWorkspace{Float64, Float64, Vector{Float64}}}()
const store_lnlq_cf32 = Dict{Ptr{Cvoid}, Krylov.LnlqWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_lnlq_cf64 = Dict{Ptr{Cvoid}, Krylov.LnlqWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_gpmr_f32 = Dict{Ptr{Cvoid}, Krylov.GpmrWorkspace{Float32, Float32, Vector{Float32}}}()
const store_gpmr_f64 = Dict{Ptr{Cvoid}, Krylov.GpmrWorkspace{Float64, Float64, Vector{Float64}}}()
const store_gpmr_cf32 = Dict{Ptr{Cvoid}, Krylov.GpmrWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_gpmr_cf64 = Dict{Ptr{Cvoid}, Krylov.GpmrWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_car_f32 = Dict{Ptr{Cvoid}, Krylov.CarWorkspace{Float32, Float32, Vector{Float32}}}()
const store_car_f64 = Dict{Ptr{Cvoid}, Krylov.CarWorkspace{Float64, Float64, Vector{Float64}}}()
const store_car_cf32 = Dict{Ptr{Cvoid}, Krylov.CarWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_car_cf64 = Dict{Ptr{Cvoid}, Krylov.CarWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

const store_minares_f32 = Dict{Ptr{Cvoid}, Krylov.MinaresWorkspace{Float32, Float32, Vector{Float32}}}()
const store_minares_f64 = Dict{Ptr{Cvoid}, Krylov.MinaresWorkspace{Float64, Float64, Vector{Float64}}}()
const store_minares_cf32 = Dict{Ptr{Cvoid}, Krylov.MinaresWorkspace{Float32, ComplexF32, Vector{ComplexF32}}}()
const store_minares_cf64 = Dict{Ptr{Cvoid}, Krylov.MinaresWorkspace{Float64, ComplexF64, Vector{ComplexF64}}}()

# Single index: handle → combo key (UInt8, max=135)
const ws_key_store = Dict{Ptr{Cvoid}, UInt8}()

# ---------------------------------------------------------------------------
# Generic typed helpers — specialized per concrete workspace type by the compiler.
# Called from within if-elseif branches where ws has a known concrete type.
# FC is extracted via the where-clause so --trim=safe can infer it statically.
# ---------------------------------------------------------------------------

function _typed_niter(ws)
  Cint(Krylov.iteration_count(ws))
end

function _typed_is_solved(ws)
  Krylov.issolved(ws) ? Cint(1) : Cint(0)
end

function _typed_elapsed_time(ws)
  Cdouble(Krylov.elapsed_time(ws))
end

function _typed_get_x!(ws::Krylov.KrylovWorkspace{T, FC, S}, x_ptr, n) where {T, FC, S}
  x = Krylov.solution(ws, 1)
  copyto!(unsafe_wrap(Vector{FC}, Ptr{FC}(x_ptr), Int(n)), x)
  Cint(0)
end

function _typed_get_y!(ws::Krylov.KrylovWorkspace{T, FC, S}, y_ptr, m) where {T, FC, S}
  Krylov.solution_count(ws) == 2 || return Cint(-2)
  y = Krylov.solution(ws, 2)
  copyto!(unsafe_wrap(Vector{FC}, Ptr{FC}(y_ptr), Int(m)), y)
  Cint(0)
end

function _typed_warm_start!(ws::Krylov.KrylovWorkspace{T, FC, S}, x0_ptr, n) where {T, FC, S}
  # Bypass Krylov.warm_start! to avoid trim-incompatible string interpolation in its
  # error path.  We inline the same logic: allocate Δx if needed, copy x0, set flag.
  hasfield(typeof(ws), :Δx) || return Cint(-2)   # solver does not support warm start
  x0 = unsafe_wrap(Vector{FC}, Ptr{FC}(x0_ptr), Int(n))
  if isempty(ws.Δx)
    ws.Δx = similar(ws.x)
  end
  copyto!(ws.Δx, x0)
  ws.warm_start = true
  Cint(0)
end

# Two-solution warm start (BiLQR, TriLQR, USYMLQR, TriCG, TriMR, GPMR): seeds
# both the primal guess x0 (size of solution(ws, 1)) and the dual guess y0 (size
# of solution(ws, 2)).  Inlined for the same trim-safety reason as above.
# nx / ny are the buffer lengths the caller passed; they must match ws.x / ws.y.
function _typed_warm_start2!(ws::Krylov.KrylovWorkspace{T, FC, S}, x0_ptr, y0_ptr, nx, ny) where {T, FC, S}
  hasfield(typeof(ws), :Δy) || return Cint(-2)   # not a two-solution solver
  (Int(nx) == length(ws.x) && Int(ny) == length(ws.y)) || return Cint(-1)
  x0 = unsafe_wrap(Vector{FC}, Ptr{FC}(x0_ptr), Int(nx))
  y0 = unsafe_wrap(Vector{FC}, Ptr{FC}(y0_ptr), Int(ny))
  isempty(ws.Δx) && (ws.Δx = similar(ws.x))
  isempty(ws.Δy) && (ws.Δy = similar(ws.y))
  copyto!(ws.Δx, x0)
  copyto!(ws.Δy, y0)
  ws.warm_start = true
  Cint(0)
end

# ---------------------------------------------------------------------------
# _opts_kw — build base keyword arguments from a KrylovOptionsC struct.
# NaN sentinels fall back to the Julia solver default (√eps(T); timemax → Inf).
# itmax=0 is always passed explicitly; Krylov.jl interprets 0 as "use default".
# atol/rtol/itmax/verbose/timemax are accepted by EVERY solver, so they live here.
# The NamedTuple type is always the same concrete type — compatible with --trim=safe.
# ---------------------------------------------------------------------------
function _opts_kw(opts::KrylovOptionsC, ::Type{T}) where T
  atol_v = isnan(opts.atol) ? sqrt(eps(T)) : T(opts.atol)
  rtol_v = isnan(opts.rtol) ? sqrt(eps(T)) : T(opts.rtol)
  tmax_v = isnan(opts.timemax) ? Inf : Float64(opts.timemax)
  (atol=atol_v, rtol=rtol_v, itmax=Int(opts.itmax), verbose=Int(opts.verbose), timemax=tmax_v)
end

# ---------------------------------------------------------------------------
# _typed_solve! variants — one per option family
# ---------------------------------------------------------------------------

# Every one/two-RHS _typed_solve* helper shares the same argument list (fptr_M is
# the left preconditioner, fptr_N the right one) so _do_solve! calls any of them
# uniformly.  There is one helper per *option set* (which scalar kwargs a solver
# accepts), so an option is only ever forwarded to a solver that supports it.
# Each call site lists its kwargs as literals → a statically-known concrete
# NamedTuple, required by --trim=safe.

# M only — CAR, CGNE, CRMR (and the catch-all).  fptr_N ignored.
function _typed_solve!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  if fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; kw...)
  end
  Cint(0)
end

# M + radius + linesearch — CG, CR.
function _typed_solve_cg!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  rad = T(opts.radius); ls = opts.linesearch != 0
  if fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, radius=rad, linesearch=ls, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; radius=rad, linesearch=ls, kw...)
  end
  Cint(0)
end

# M + linesearch + λ-shift — MINRES, MINRES-QLP.
function _typed_solve_minres!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  λ = T(opts.lambda); ls = opts.linesearch != 0
  if fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, λ=λ, linesearch=ls, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, linesearch=ls, kw...)
  end
  Cint(0)
end

# M + λ-shift — SYMMLQ, MINARES (symmetric, no linesearch).
function _typed_solve_sym_lambda!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  λ = T(opts.lambda)
  if fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, λ=λ, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, kw...)
  end
  Cint(0)
end

# M + N — BiCGSTAB, CGS, BiLQ, QMR.  The four NULL/non-NULL combinations are
# spelled out so each krylov_solve! call site is concretely typed (--trim=safe).
function _typed_solve_mn!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, N=N, kw...)
  elseif fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, kw...)
  elseif fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; kw...)
  end
  Cint(0)
end

# M + N + reorthogonalization — DIOM, DQGMRES (limited-memory, no restart).
function _typed_solve_mn_reorth!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  ro = opts.reorthogonalization != 0
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, N=N, reorthogonalization=ro, kw...)
  elseif fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, reorthogonalization=ro, kw...)
  elseif fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, reorthogonalization=ro, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; reorthogonalization=ro, kw...)
  end
  Cint(0)
end

# M + N + restart + reorthogonalization — GMRES, FGMRES, FOM.
function _typed_solve_gmres!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T)
  rs = opts.restart != 0; ro = opts.reorthogonalization != 0
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, N=N, restart=rs, reorthogonalization=ro, kw...)
  elseif fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, restart=rs, reorthogonalization=ro, kw...)
  elseif fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, restart=rs, reorthogonalization=ro, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; restart=rs, reorthogonalization=ro, kw...)
  end
  Cint(0)
end

# Least-squares / least-norm preconditioning follows Krylov's convention:
# M = E⁻¹ acts on the m-dimensional data space, N = F⁻¹ on the n-dimensional
# solution space (so M is sized with ws.m, N with ws.n).  λ is always passed
# (0.0 = none).  M/N combinations are spelled out for --trim=safe.

# λ + radius + M(m) + N(n) — LSQR, LSMR.
function _typed_solve_ls_mn_radius!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T); λ = T(opts.lambda); rad = T(opts.radius)
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, N=N, λ=λ, radius=rad, kw...)
  elseif fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, λ=λ, radius=rad, kw...)
  elseif fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, λ=λ, radius=rad, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, radius=rad, kw...)
  end
  Cint(0)
end

# λ + M(m) + N(n) — LSLQ, CRAIG, CRAIGMR, LNLQ (no radius).
function _typed_solve_ls_mn!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T); λ = T(opts.lambda)
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, N=N, λ=λ, kw...)
  elseif fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, λ=λ, kw...)
  elseif fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, λ=λ, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, kw...)
  end
  Cint(0)
end

# λ + radius + M(n) — CGLS, CRLS (CG/CR on the normal equations; single
# preconditioner on the n-space, passed via matvec_M).
function _typed_solve_ls_m_radius!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T); λ = T(opts.lambda); rad = T(opts.radius)
  if fptr_M != C_NULL
    M = CPreconditioner{FC}(ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, b; M=M, λ=λ, radius=rad, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, radius=rad, kw...)
  end
  Cint(0)
end

# λ + N(n) — CGNE, CRMR (single preconditioner on the n-space, via matvec_N).
function _typed_solve_ls_n!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  kw = _opts_kw(opts, T); λ = T(opts.lambda)
  if fptr_N != C_NULL
    N = CPreconditioner{FC}(ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, b; N=N, λ=λ, kw...)
  else
    Krylov.krylov_solve!(ws, A, b; λ=λ, kw...)
  end
  Cint(0)
end

# TriCG / TriMR: two-RHS + τ and ν (quasi-definite diagonal parameters).
# NaN sentinel → use Krylov.jl defaults (τ=1.0, ν=-1.0).  M/N ignored.
function _typed_solve_tau_nu!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  c  = unsafe_wrap(Vector{FC}, Ptr{FC}(c_ptr), ws.n)
  kw = _opts_kw(opts, T)
  τ  = isnan(opts.tau) ? T(1)  : T(opts.tau)
  ν  = isnan(opts.nu)  ? T(-1) : T(opts.nu)
  Krylov.krylov_solve!(ws, A, b, c; τ=τ, ν=ν, kw...)
  Cint(0)
end

# Basic two-RHS solvers (BiLQR / TriLQR / USYMLQ / USYMQR / USYMLQR).  M/N ignored.
function _typed_solve_two_rhs!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, fptr_At, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  c  = unsafe_wrap(Vector{FC}, Ptr{FC}(c_ptr), ws.n)
  kw = _opts_kw(opts, T)
  Krylov.krylov_solve!(ws, A, b, c; kw...)
  Cint(0)
end

# GPMR — fptr_At slot is repurposed as B (n×m), distinct from A (m×n).
# GPMR has its own preconditioner family (C, D, E, F), not exposed: M/N ignored.
# It does accept reorthogonalization.
function _typed_solve_gpmr!(ws::Krylov.KrylovWorkspace{T, FC, S}, fptr_A, fptr_B, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts) where {T, FC, S}
  A  = COperator{FC}(ws.m, ws.n, fptr_A, C_NULL, userdata)
  B  = COperator{FC}(ws.n, ws.m, fptr_B, C_NULL, userdata)
  b  = unsafe_wrap(Vector{FC}, Ptr{FC}(b_ptr), ws.m)
  c  = unsafe_wrap(Vector{FC}, Ptr{FC}(c_ptr), ws.n)
  kw = _opts_kw(opts, T)
  Krylov.krylov_solve!(ws, A, B, b, c; reorthogonalization=(opts.reorthogonalization != 0), kw...)
  Cint(0)
end

# ---------------------------------------------------------------------------
# Dispatch functions — generated if-elseif chains over all 136 combos.
# Each branch has a statically known concrete type: compatible with --trim=safe.
# ---------------------------------------------------------------------------

function _do_niter(ws_ptr :: Ptr{Cvoid})
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_niter(store_cg_f32[ws_ptr])
  elseif k == 0x01; _typed_niter(store_cg_f64[ws_ptr])
  elseif k == 0x02; _typed_niter(store_cg_cf32[ws_ptr])
  elseif k == 0x03; _typed_niter(store_cg_cf64[ws_ptr])
  elseif k == 0x04; _typed_niter(store_cr_f32[ws_ptr])
  elseif k == 0x05; _typed_niter(store_cr_f64[ws_ptr])
  elseif k == 0x06; _typed_niter(store_cr_cf32[ws_ptr])
  elseif k == 0x07; _typed_niter(store_cr_cf64[ws_ptr])
  elseif k == 0x08; _typed_niter(store_symmlq_f32[ws_ptr])
  elseif k == 0x09; _typed_niter(store_symmlq_f64[ws_ptr])
  elseif k == 0x0a; _typed_niter(store_symmlq_cf32[ws_ptr])
  elseif k == 0x0b; _typed_niter(store_symmlq_cf64[ws_ptr])
  elseif k == 0x0c; _typed_niter(store_minres_f32[ws_ptr])
  elseif k == 0x0d; _typed_niter(store_minres_f64[ws_ptr])
  elseif k == 0x0e; _typed_niter(store_minres_cf32[ws_ptr])
  elseif k == 0x0f; _typed_niter(store_minres_cf64[ws_ptr])
  elseif k == 0x10; _typed_niter(store_minres_qlp_f32[ws_ptr])
  elseif k == 0x11; _typed_niter(store_minres_qlp_f64[ws_ptr])
  elseif k == 0x12; _typed_niter(store_minres_qlp_cf32[ws_ptr])
  elseif k == 0x13; _typed_niter(store_minres_qlp_cf64[ws_ptr])
  elseif k == 0x14; _typed_niter(store_diom_f32[ws_ptr])
  elseif k == 0x15; _typed_niter(store_diom_f64[ws_ptr])
  elseif k == 0x16; _typed_niter(store_diom_cf32[ws_ptr])
  elseif k == 0x17; _typed_niter(store_diom_cf64[ws_ptr])
  elseif k == 0x18; _typed_niter(store_dqgmres_f32[ws_ptr])
  elseif k == 0x19; _typed_niter(store_dqgmres_f64[ws_ptr])
  elseif k == 0x1a; _typed_niter(store_dqgmres_cf32[ws_ptr])
  elseif k == 0x1b; _typed_niter(store_dqgmres_cf64[ws_ptr])
  elseif k == 0x1c; _typed_niter(store_fom_f32[ws_ptr])
  elseif k == 0x1d; _typed_niter(store_fom_f64[ws_ptr])
  elseif k == 0x1e; _typed_niter(store_fom_cf32[ws_ptr])
  elseif k == 0x1f; _typed_niter(store_fom_cf64[ws_ptr])
  elseif k == 0x20; _typed_niter(store_gmres_f32[ws_ptr])
  elseif k == 0x21; _typed_niter(store_gmres_f64[ws_ptr])
  elseif k == 0x22; _typed_niter(store_gmres_cf32[ws_ptr])
  elseif k == 0x23; _typed_niter(store_gmres_cf64[ws_ptr])
  elseif k == 0x24; _typed_niter(store_fgmres_f32[ws_ptr])
  elseif k == 0x25; _typed_niter(store_fgmres_f64[ws_ptr])
  elseif k == 0x26; _typed_niter(store_fgmres_cf32[ws_ptr])
  elseif k == 0x27; _typed_niter(store_fgmres_cf64[ws_ptr])
  elseif k == 0x28; _typed_niter(store_bicgstab_f32[ws_ptr])
  elseif k == 0x29; _typed_niter(store_bicgstab_f64[ws_ptr])
  elseif k == 0x2a; _typed_niter(store_bicgstab_cf32[ws_ptr])
  elseif k == 0x2b; _typed_niter(store_bicgstab_cf64[ws_ptr])
  elseif k == 0x2c; _typed_niter(store_cgs_f32[ws_ptr])
  elseif k == 0x2d; _typed_niter(store_cgs_f64[ws_ptr])
  elseif k == 0x2e; _typed_niter(store_cgs_cf32[ws_ptr])
  elseif k == 0x2f; _typed_niter(store_cgs_cf64[ws_ptr])
  elseif k == 0x30; _typed_niter(store_bilq_f32[ws_ptr])
  elseif k == 0x31; _typed_niter(store_bilq_f64[ws_ptr])
  elseif k == 0x32; _typed_niter(store_bilq_cf32[ws_ptr])
  elseif k == 0x33; _typed_niter(store_bilq_cf64[ws_ptr])
  elseif k == 0x34; _typed_niter(store_qmr_f32[ws_ptr])
  elseif k == 0x35; _typed_niter(store_qmr_f64[ws_ptr])
  elseif k == 0x36; _typed_niter(store_qmr_cf32[ws_ptr])
  elseif k == 0x37; _typed_niter(store_qmr_cf64[ws_ptr])
  elseif k == 0x38; _typed_niter(store_usymlq_f32[ws_ptr])
  elseif k == 0x39; _typed_niter(store_usymlq_f64[ws_ptr])
  elseif k == 0x3a; _typed_niter(store_usymlq_cf32[ws_ptr])
  elseif k == 0x3b; _typed_niter(store_usymlq_cf64[ws_ptr])
  elseif k == 0x3c; _typed_niter(store_usymqr_f32[ws_ptr])
  elseif k == 0x3d; _typed_niter(store_usymqr_f64[ws_ptr])
  elseif k == 0x3e; _typed_niter(store_usymqr_cf32[ws_ptr])
  elseif k == 0x3f; _typed_niter(store_usymqr_cf64[ws_ptr])
  elseif k == 0x40; _typed_niter(store_tricg_f32[ws_ptr])
  elseif k == 0x41; _typed_niter(store_tricg_f64[ws_ptr])
  elseif k == 0x42; _typed_niter(store_tricg_cf32[ws_ptr])
  elseif k == 0x43; _typed_niter(store_tricg_cf64[ws_ptr])
  elseif k == 0x44; _typed_niter(store_trimr_f32[ws_ptr])
  elseif k == 0x45; _typed_niter(store_trimr_f64[ws_ptr])
  elseif k == 0x46; _typed_niter(store_trimr_cf32[ws_ptr])
  elseif k == 0x47; _typed_niter(store_trimr_cf64[ws_ptr])
  elseif k == 0x48; _typed_niter(store_trilqr_f32[ws_ptr])
  elseif k == 0x49; _typed_niter(store_trilqr_f64[ws_ptr])
  elseif k == 0x4a; _typed_niter(store_trilqr_cf32[ws_ptr])
  elseif k == 0x4b; _typed_niter(store_trilqr_cf64[ws_ptr])
  elseif k == 0x4c; _typed_niter(store_bilqr_f32[ws_ptr])
  elseif k == 0x4d; _typed_niter(store_bilqr_f64[ws_ptr])
  elseif k == 0x4e; _typed_niter(store_bilqr_cf32[ws_ptr])
  elseif k == 0x4f; _typed_niter(store_bilqr_cf64[ws_ptr])
  elseif k == 0x50; _typed_niter(store_lslq_f32[ws_ptr])
  elseif k == 0x51; _typed_niter(store_lslq_f64[ws_ptr])
  elseif k == 0x52; _typed_niter(store_lslq_cf32[ws_ptr])
  elseif k == 0x53; _typed_niter(store_lslq_cf64[ws_ptr])
  elseif k == 0x54; _typed_niter(store_lsqr_f32[ws_ptr])
  elseif k == 0x55; _typed_niter(store_lsqr_f64[ws_ptr])
  elseif k == 0x56; _typed_niter(store_lsqr_cf32[ws_ptr])
  elseif k == 0x57; _typed_niter(store_lsqr_cf64[ws_ptr])
  elseif k == 0x58; _typed_niter(store_lsmr_f32[ws_ptr])
  elseif k == 0x59; _typed_niter(store_lsmr_f64[ws_ptr])
  elseif k == 0x5a; _typed_niter(store_lsmr_cf32[ws_ptr])
  elseif k == 0x5b; _typed_niter(store_lsmr_cf64[ws_ptr])
  elseif k == 0x5c; _typed_niter(store_usymlqr_f32[ws_ptr])
  elseif k == 0x5d; _typed_niter(store_usymlqr_f64[ws_ptr])
  elseif k == 0x5e; _typed_niter(store_usymlqr_cf32[ws_ptr])
  elseif k == 0x5f; _typed_niter(store_usymlqr_cf64[ws_ptr])
  elseif k == 0x60; _typed_niter(store_cgls_f32[ws_ptr])
  elseif k == 0x61; _typed_niter(store_cgls_f64[ws_ptr])
  elseif k == 0x62; _typed_niter(store_cgls_cf32[ws_ptr])
  elseif k == 0x63; _typed_niter(store_cgls_cf64[ws_ptr])
  elseif k == 0x64; _typed_niter(store_crls_f32[ws_ptr])
  elseif k == 0x65; _typed_niter(store_crls_f64[ws_ptr])
  elseif k == 0x66; _typed_niter(store_crls_cf32[ws_ptr])
  elseif k == 0x67; _typed_niter(store_crls_cf64[ws_ptr])
  elseif k == 0x68; _typed_niter(store_cgne_f32[ws_ptr])
  elseif k == 0x69; _typed_niter(store_cgne_f64[ws_ptr])
  elseif k == 0x6a; _typed_niter(store_cgne_cf32[ws_ptr])
  elseif k == 0x6b; _typed_niter(store_cgne_cf64[ws_ptr])
  elseif k == 0x6c; _typed_niter(store_crmr_f32[ws_ptr])
  elseif k == 0x6d; _typed_niter(store_crmr_f64[ws_ptr])
  elseif k == 0x6e; _typed_niter(store_crmr_cf32[ws_ptr])
  elseif k == 0x6f; _typed_niter(store_crmr_cf64[ws_ptr])
  elseif k == 0x70; _typed_niter(store_craig_f32[ws_ptr])
  elseif k == 0x71; _typed_niter(store_craig_f64[ws_ptr])
  elseif k == 0x72; _typed_niter(store_craig_cf32[ws_ptr])
  elseif k == 0x73; _typed_niter(store_craig_cf64[ws_ptr])
  elseif k == 0x74; _typed_niter(store_craigmr_f32[ws_ptr])
  elseif k == 0x75; _typed_niter(store_craigmr_f64[ws_ptr])
  elseif k == 0x76; _typed_niter(store_craigmr_cf32[ws_ptr])
  elseif k == 0x77; _typed_niter(store_craigmr_cf64[ws_ptr])
  elseif k == 0x78; _typed_niter(store_lnlq_f32[ws_ptr])
  elseif k == 0x79; _typed_niter(store_lnlq_f64[ws_ptr])
  elseif k == 0x7a; _typed_niter(store_lnlq_cf32[ws_ptr])
  elseif k == 0x7b; _typed_niter(store_lnlq_cf64[ws_ptr])
  elseif k == 0x7c; _typed_niter(store_gpmr_f32[ws_ptr])
  elseif k == 0x7d; _typed_niter(store_gpmr_f64[ws_ptr])
  elseif k == 0x7e; _typed_niter(store_gpmr_cf32[ws_ptr])
  elseif k == 0x7f; _typed_niter(store_gpmr_cf64[ws_ptr])
  elseif k == 0x80; _typed_niter(store_car_f32[ws_ptr])
  elseif k == 0x81; _typed_niter(store_car_f64[ws_ptr])
  elseif k == 0x82; _typed_niter(store_car_cf32[ws_ptr])
  elseif k == 0x83; _typed_niter(store_car_cf64[ws_ptr])
  elseif k == 0x84; _typed_niter(store_minares_f32[ws_ptr])
  elseif k == 0x85; _typed_niter(store_minares_f64[ws_ptr])
  elseif k == 0x86; _typed_niter(store_minares_cf32[ws_ptr])
  elseif k == 0x87; _typed_niter(store_minares_cf64[ws_ptr])
  else; Cint(-1); end
end

function _do_is_solved(ws_ptr :: Ptr{Cvoid})
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_is_solved(store_cg_f32[ws_ptr])
  elseif k == 0x01; _typed_is_solved(store_cg_f64[ws_ptr])
  elseif k == 0x02; _typed_is_solved(store_cg_cf32[ws_ptr])
  elseif k == 0x03; _typed_is_solved(store_cg_cf64[ws_ptr])
  elseif k == 0x04; _typed_is_solved(store_cr_f32[ws_ptr])
  elseif k == 0x05; _typed_is_solved(store_cr_f64[ws_ptr])
  elseif k == 0x06; _typed_is_solved(store_cr_cf32[ws_ptr])
  elseif k == 0x07; _typed_is_solved(store_cr_cf64[ws_ptr])
  elseif k == 0x08; _typed_is_solved(store_symmlq_f32[ws_ptr])
  elseif k == 0x09; _typed_is_solved(store_symmlq_f64[ws_ptr])
  elseif k == 0x0a; _typed_is_solved(store_symmlq_cf32[ws_ptr])
  elseif k == 0x0b; _typed_is_solved(store_symmlq_cf64[ws_ptr])
  elseif k == 0x0c; _typed_is_solved(store_minres_f32[ws_ptr])
  elseif k == 0x0d; _typed_is_solved(store_minres_f64[ws_ptr])
  elseif k == 0x0e; _typed_is_solved(store_minres_cf32[ws_ptr])
  elseif k == 0x0f; _typed_is_solved(store_minres_cf64[ws_ptr])
  elseif k == 0x10; _typed_is_solved(store_minres_qlp_f32[ws_ptr])
  elseif k == 0x11; _typed_is_solved(store_minres_qlp_f64[ws_ptr])
  elseif k == 0x12; _typed_is_solved(store_minres_qlp_cf32[ws_ptr])
  elseif k == 0x13; _typed_is_solved(store_minres_qlp_cf64[ws_ptr])
  elseif k == 0x14; _typed_is_solved(store_diom_f32[ws_ptr])
  elseif k == 0x15; _typed_is_solved(store_diom_f64[ws_ptr])
  elseif k == 0x16; _typed_is_solved(store_diom_cf32[ws_ptr])
  elseif k == 0x17; _typed_is_solved(store_diom_cf64[ws_ptr])
  elseif k == 0x18; _typed_is_solved(store_dqgmres_f32[ws_ptr])
  elseif k == 0x19; _typed_is_solved(store_dqgmres_f64[ws_ptr])
  elseif k == 0x1a; _typed_is_solved(store_dqgmres_cf32[ws_ptr])
  elseif k == 0x1b; _typed_is_solved(store_dqgmres_cf64[ws_ptr])
  elseif k == 0x1c; _typed_is_solved(store_fom_f32[ws_ptr])
  elseif k == 0x1d; _typed_is_solved(store_fom_f64[ws_ptr])
  elseif k == 0x1e; _typed_is_solved(store_fom_cf32[ws_ptr])
  elseif k == 0x1f; _typed_is_solved(store_fom_cf64[ws_ptr])
  elseif k == 0x20; _typed_is_solved(store_gmres_f32[ws_ptr])
  elseif k == 0x21; _typed_is_solved(store_gmres_f64[ws_ptr])
  elseif k == 0x22; _typed_is_solved(store_gmres_cf32[ws_ptr])
  elseif k == 0x23; _typed_is_solved(store_gmres_cf64[ws_ptr])
  elseif k == 0x24; _typed_is_solved(store_fgmres_f32[ws_ptr])
  elseif k == 0x25; _typed_is_solved(store_fgmres_f64[ws_ptr])
  elseif k == 0x26; _typed_is_solved(store_fgmres_cf32[ws_ptr])
  elseif k == 0x27; _typed_is_solved(store_fgmres_cf64[ws_ptr])
  elseif k == 0x28; _typed_is_solved(store_bicgstab_f32[ws_ptr])
  elseif k == 0x29; _typed_is_solved(store_bicgstab_f64[ws_ptr])
  elseif k == 0x2a; _typed_is_solved(store_bicgstab_cf32[ws_ptr])
  elseif k == 0x2b; _typed_is_solved(store_bicgstab_cf64[ws_ptr])
  elseif k == 0x2c; _typed_is_solved(store_cgs_f32[ws_ptr])
  elseif k == 0x2d; _typed_is_solved(store_cgs_f64[ws_ptr])
  elseif k == 0x2e; _typed_is_solved(store_cgs_cf32[ws_ptr])
  elseif k == 0x2f; _typed_is_solved(store_cgs_cf64[ws_ptr])
  elseif k == 0x30; _typed_is_solved(store_bilq_f32[ws_ptr])
  elseif k == 0x31; _typed_is_solved(store_bilq_f64[ws_ptr])
  elseif k == 0x32; _typed_is_solved(store_bilq_cf32[ws_ptr])
  elseif k == 0x33; _typed_is_solved(store_bilq_cf64[ws_ptr])
  elseif k == 0x34; _typed_is_solved(store_qmr_f32[ws_ptr])
  elseif k == 0x35; _typed_is_solved(store_qmr_f64[ws_ptr])
  elseif k == 0x36; _typed_is_solved(store_qmr_cf32[ws_ptr])
  elseif k == 0x37; _typed_is_solved(store_qmr_cf64[ws_ptr])
  elseif k == 0x38; _typed_is_solved(store_usymlq_f32[ws_ptr])
  elseif k == 0x39; _typed_is_solved(store_usymlq_f64[ws_ptr])
  elseif k == 0x3a; _typed_is_solved(store_usymlq_cf32[ws_ptr])
  elseif k == 0x3b; _typed_is_solved(store_usymlq_cf64[ws_ptr])
  elseif k == 0x3c; _typed_is_solved(store_usymqr_f32[ws_ptr])
  elseif k == 0x3d; _typed_is_solved(store_usymqr_f64[ws_ptr])
  elseif k == 0x3e; _typed_is_solved(store_usymqr_cf32[ws_ptr])
  elseif k == 0x3f; _typed_is_solved(store_usymqr_cf64[ws_ptr])
  elseif k == 0x40; _typed_is_solved(store_tricg_f32[ws_ptr])
  elseif k == 0x41; _typed_is_solved(store_tricg_f64[ws_ptr])
  elseif k == 0x42; _typed_is_solved(store_tricg_cf32[ws_ptr])
  elseif k == 0x43; _typed_is_solved(store_tricg_cf64[ws_ptr])
  elseif k == 0x44; _typed_is_solved(store_trimr_f32[ws_ptr])
  elseif k == 0x45; _typed_is_solved(store_trimr_f64[ws_ptr])
  elseif k == 0x46; _typed_is_solved(store_trimr_cf32[ws_ptr])
  elseif k == 0x47; _typed_is_solved(store_trimr_cf64[ws_ptr])
  elseif k == 0x48; _typed_is_solved(store_trilqr_f32[ws_ptr])
  elseif k == 0x49; _typed_is_solved(store_trilqr_f64[ws_ptr])
  elseif k == 0x4a; _typed_is_solved(store_trilqr_cf32[ws_ptr])
  elseif k == 0x4b; _typed_is_solved(store_trilqr_cf64[ws_ptr])
  elseif k == 0x4c; _typed_is_solved(store_bilqr_f32[ws_ptr])
  elseif k == 0x4d; _typed_is_solved(store_bilqr_f64[ws_ptr])
  elseif k == 0x4e; _typed_is_solved(store_bilqr_cf32[ws_ptr])
  elseif k == 0x4f; _typed_is_solved(store_bilqr_cf64[ws_ptr])
  elseif k == 0x50; _typed_is_solved(store_lslq_f32[ws_ptr])
  elseif k == 0x51; _typed_is_solved(store_lslq_f64[ws_ptr])
  elseif k == 0x52; _typed_is_solved(store_lslq_cf32[ws_ptr])
  elseif k == 0x53; _typed_is_solved(store_lslq_cf64[ws_ptr])
  elseif k == 0x54; _typed_is_solved(store_lsqr_f32[ws_ptr])
  elseif k == 0x55; _typed_is_solved(store_lsqr_f64[ws_ptr])
  elseif k == 0x56; _typed_is_solved(store_lsqr_cf32[ws_ptr])
  elseif k == 0x57; _typed_is_solved(store_lsqr_cf64[ws_ptr])
  elseif k == 0x58; _typed_is_solved(store_lsmr_f32[ws_ptr])
  elseif k == 0x59; _typed_is_solved(store_lsmr_f64[ws_ptr])
  elseif k == 0x5a; _typed_is_solved(store_lsmr_cf32[ws_ptr])
  elseif k == 0x5b; _typed_is_solved(store_lsmr_cf64[ws_ptr])
  elseif k == 0x5c; _typed_is_solved(store_usymlqr_f32[ws_ptr])
  elseif k == 0x5d; _typed_is_solved(store_usymlqr_f64[ws_ptr])
  elseif k == 0x5e; _typed_is_solved(store_usymlqr_cf32[ws_ptr])
  elseif k == 0x5f; _typed_is_solved(store_usymlqr_cf64[ws_ptr])
  elseif k == 0x60; _typed_is_solved(store_cgls_f32[ws_ptr])
  elseif k == 0x61; _typed_is_solved(store_cgls_f64[ws_ptr])
  elseif k == 0x62; _typed_is_solved(store_cgls_cf32[ws_ptr])
  elseif k == 0x63; _typed_is_solved(store_cgls_cf64[ws_ptr])
  elseif k == 0x64; _typed_is_solved(store_crls_f32[ws_ptr])
  elseif k == 0x65; _typed_is_solved(store_crls_f64[ws_ptr])
  elseif k == 0x66; _typed_is_solved(store_crls_cf32[ws_ptr])
  elseif k == 0x67; _typed_is_solved(store_crls_cf64[ws_ptr])
  elseif k == 0x68; _typed_is_solved(store_cgne_f32[ws_ptr])
  elseif k == 0x69; _typed_is_solved(store_cgne_f64[ws_ptr])
  elseif k == 0x6a; _typed_is_solved(store_cgne_cf32[ws_ptr])
  elseif k == 0x6b; _typed_is_solved(store_cgne_cf64[ws_ptr])
  elseif k == 0x6c; _typed_is_solved(store_crmr_f32[ws_ptr])
  elseif k == 0x6d; _typed_is_solved(store_crmr_f64[ws_ptr])
  elseif k == 0x6e; _typed_is_solved(store_crmr_cf32[ws_ptr])
  elseif k == 0x6f; _typed_is_solved(store_crmr_cf64[ws_ptr])
  elseif k == 0x70; _typed_is_solved(store_craig_f32[ws_ptr])
  elseif k == 0x71; _typed_is_solved(store_craig_f64[ws_ptr])
  elseif k == 0x72; _typed_is_solved(store_craig_cf32[ws_ptr])
  elseif k == 0x73; _typed_is_solved(store_craig_cf64[ws_ptr])
  elseif k == 0x74; _typed_is_solved(store_craigmr_f32[ws_ptr])
  elseif k == 0x75; _typed_is_solved(store_craigmr_f64[ws_ptr])
  elseif k == 0x76; _typed_is_solved(store_craigmr_cf32[ws_ptr])
  elseif k == 0x77; _typed_is_solved(store_craigmr_cf64[ws_ptr])
  elseif k == 0x78; _typed_is_solved(store_lnlq_f32[ws_ptr])
  elseif k == 0x79; _typed_is_solved(store_lnlq_f64[ws_ptr])
  elseif k == 0x7a; _typed_is_solved(store_lnlq_cf32[ws_ptr])
  elseif k == 0x7b; _typed_is_solved(store_lnlq_cf64[ws_ptr])
  elseif k == 0x7c; _typed_is_solved(store_gpmr_f32[ws_ptr])
  elseif k == 0x7d; _typed_is_solved(store_gpmr_f64[ws_ptr])
  elseif k == 0x7e; _typed_is_solved(store_gpmr_cf32[ws_ptr])
  elseif k == 0x7f; _typed_is_solved(store_gpmr_cf64[ws_ptr])
  elseif k == 0x80; _typed_is_solved(store_car_f32[ws_ptr])
  elseif k == 0x81; _typed_is_solved(store_car_f64[ws_ptr])
  elseif k == 0x82; _typed_is_solved(store_car_cf32[ws_ptr])
  elseif k == 0x83; _typed_is_solved(store_car_cf64[ws_ptr])
  elseif k == 0x84; _typed_is_solved(store_minares_f32[ws_ptr])
  elseif k == 0x85; _typed_is_solved(store_minares_f64[ws_ptr])
  elseif k == 0x86; _typed_is_solved(store_minares_cf32[ws_ptr])
  elseif k == 0x87; _typed_is_solved(store_minares_cf64[ws_ptr])
  else; Cint(-1); end
end

function _do_elapsed_time(ws_ptr :: Ptr{Cvoid})
  haskey(ws_key_store, ws_ptr) || return Cdouble(-1.0)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_elapsed_time(store_cg_f32[ws_ptr])
  elseif k == 0x01; _typed_elapsed_time(store_cg_f64[ws_ptr])
  elseif k == 0x02; _typed_elapsed_time(store_cg_cf32[ws_ptr])
  elseif k == 0x03; _typed_elapsed_time(store_cg_cf64[ws_ptr])
  elseif k == 0x04; _typed_elapsed_time(store_cr_f32[ws_ptr])
  elseif k == 0x05; _typed_elapsed_time(store_cr_f64[ws_ptr])
  elseif k == 0x06; _typed_elapsed_time(store_cr_cf32[ws_ptr])
  elseif k == 0x07; _typed_elapsed_time(store_cr_cf64[ws_ptr])
  elseif k == 0x08; _typed_elapsed_time(store_symmlq_f32[ws_ptr])
  elseif k == 0x09; _typed_elapsed_time(store_symmlq_f64[ws_ptr])
  elseif k == 0x0a; _typed_elapsed_time(store_symmlq_cf32[ws_ptr])
  elseif k == 0x0b; _typed_elapsed_time(store_symmlq_cf64[ws_ptr])
  elseif k == 0x0c; _typed_elapsed_time(store_minres_f32[ws_ptr])
  elseif k == 0x0d; _typed_elapsed_time(store_minres_f64[ws_ptr])
  elseif k == 0x0e; _typed_elapsed_time(store_minres_cf32[ws_ptr])
  elseif k == 0x0f; _typed_elapsed_time(store_minres_cf64[ws_ptr])
  elseif k == 0x10; _typed_elapsed_time(store_minres_qlp_f32[ws_ptr])
  elseif k == 0x11; _typed_elapsed_time(store_minres_qlp_f64[ws_ptr])
  elseif k == 0x12; _typed_elapsed_time(store_minres_qlp_cf32[ws_ptr])
  elseif k == 0x13; _typed_elapsed_time(store_minres_qlp_cf64[ws_ptr])
  elseif k == 0x14; _typed_elapsed_time(store_diom_f32[ws_ptr])
  elseif k == 0x15; _typed_elapsed_time(store_diom_f64[ws_ptr])
  elseif k == 0x16; _typed_elapsed_time(store_diom_cf32[ws_ptr])
  elseif k == 0x17; _typed_elapsed_time(store_diom_cf64[ws_ptr])
  elseif k == 0x18; _typed_elapsed_time(store_dqgmres_f32[ws_ptr])
  elseif k == 0x19; _typed_elapsed_time(store_dqgmres_f64[ws_ptr])
  elseif k == 0x1a; _typed_elapsed_time(store_dqgmres_cf32[ws_ptr])
  elseif k == 0x1b; _typed_elapsed_time(store_dqgmres_cf64[ws_ptr])
  elseif k == 0x1c; _typed_elapsed_time(store_fom_f32[ws_ptr])
  elseif k == 0x1d; _typed_elapsed_time(store_fom_f64[ws_ptr])
  elseif k == 0x1e; _typed_elapsed_time(store_fom_cf32[ws_ptr])
  elseif k == 0x1f; _typed_elapsed_time(store_fom_cf64[ws_ptr])
  elseif k == 0x20; _typed_elapsed_time(store_gmres_f32[ws_ptr])
  elseif k == 0x21; _typed_elapsed_time(store_gmres_f64[ws_ptr])
  elseif k == 0x22; _typed_elapsed_time(store_gmres_cf32[ws_ptr])
  elseif k == 0x23; _typed_elapsed_time(store_gmres_cf64[ws_ptr])
  elseif k == 0x24; _typed_elapsed_time(store_fgmres_f32[ws_ptr])
  elseif k == 0x25; _typed_elapsed_time(store_fgmres_f64[ws_ptr])
  elseif k == 0x26; _typed_elapsed_time(store_fgmres_cf32[ws_ptr])
  elseif k == 0x27; _typed_elapsed_time(store_fgmres_cf64[ws_ptr])
  elseif k == 0x28; _typed_elapsed_time(store_bicgstab_f32[ws_ptr])
  elseif k == 0x29; _typed_elapsed_time(store_bicgstab_f64[ws_ptr])
  elseif k == 0x2a; _typed_elapsed_time(store_bicgstab_cf32[ws_ptr])
  elseif k == 0x2b; _typed_elapsed_time(store_bicgstab_cf64[ws_ptr])
  elseif k == 0x2c; _typed_elapsed_time(store_cgs_f32[ws_ptr])
  elseif k == 0x2d; _typed_elapsed_time(store_cgs_f64[ws_ptr])
  elseif k == 0x2e; _typed_elapsed_time(store_cgs_cf32[ws_ptr])
  elseif k == 0x2f; _typed_elapsed_time(store_cgs_cf64[ws_ptr])
  elseif k == 0x30; _typed_elapsed_time(store_bilq_f32[ws_ptr])
  elseif k == 0x31; _typed_elapsed_time(store_bilq_f64[ws_ptr])
  elseif k == 0x32; _typed_elapsed_time(store_bilq_cf32[ws_ptr])
  elseif k == 0x33; _typed_elapsed_time(store_bilq_cf64[ws_ptr])
  elseif k == 0x34; _typed_elapsed_time(store_qmr_f32[ws_ptr])
  elseif k == 0x35; _typed_elapsed_time(store_qmr_f64[ws_ptr])
  elseif k == 0x36; _typed_elapsed_time(store_qmr_cf32[ws_ptr])
  elseif k == 0x37; _typed_elapsed_time(store_qmr_cf64[ws_ptr])
  elseif k == 0x38; _typed_elapsed_time(store_usymlq_f32[ws_ptr])
  elseif k == 0x39; _typed_elapsed_time(store_usymlq_f64[ws_ptr])
  elseif k == 0x3a; _typed_elapsed_time(store_usymlq_cf32[ws_ptr])
  elseif k == 0x3b; _typed_elapsed_time(store_usymlq_cf64[ws_ptr])
  elseif k == 0x3c; _typed_elapsed_time(store_usymqr_f32[ws_ptr])
  elseif k == 0x3d; _typed_elapsed_time(store_usymqr_f64[ws_ptr])
  elseif k == 0x3e; _typed_elapsed_time(store_usymqr_cf32[ws_ptr])
  elseif k == 0x3f; _typed_elapsed_time(store_usymqr_cf64[ws_ptr])
  elseif k == 0x40; _typed_elapsed_time(store_tricg_f32[ws_ptr])
  elseif k == 0x41; _typed_elapsed_time(store_tricg_f64[ws_ptr])
  elseif k == 0x42; _typed_elapsed_time(store_tricg_cf32[ws_ptr])
  elseif k == 0x43; _typed_elapsed_time(store_tricg_cf64[ws_ptr])
  elseif k == 0x44; _typed_elapsed_time(store_trimr_f32[ws_ptr])
  elseif k == 0x45; _typed_elapsed_time(store_trimr_f64[ws_ptr])
  elseif k == 0x46; _typed_elapsed_time(store_trimr_cf32[ws_ptr])
  elseif k == 0x47; _typed_elapsed_time(store_trimr_cf64[ws_ptr])
  elseif k == 0x48; _typed_elapsed_time(store_trilqr_f32[ws_ptr])
  elseif k == 0x49; _typed_elapsed_time(store_trilqr_f64[ws_ptr])
  elseif k == 0x4a; _typed_elapsed_time(store_trilqr_cf32[ws_ptr])
  elseif k == 0x4b; _typed_elapsed_time(store_trilqr_cf64[ws_ptr])
  elseif k == 0x4c; _typed_elapsed_time(store_bilqr_f32[ws_ptr])
  elseif k == 0x4d; _typed_elapsed_time(store_bilqr_f64[ws_ptr])
  elseif k == 0x4e; _typed_elapsed_time(store_bilqr_cf32[ws_ptr])
  elseif k == 0x4f; _typed_elapsed_time(store_bilqr_cf64[ws_ptr])
  elseif k == 0x50; _typed_elapsed_time(store_lslq_f32[ws_ptr])
  elseif k == 0x51; _typed_elapsed_time(store_lslq_f64[ws_ptr])
  elseif k == 0x52; _typed_elapsed_time(store_lslq_cf32[ws_ptr])
  elseif k == 0x53; _typed_elapsed_time(store_lslq_cf64[ws_ptr])
  elseif k == 0x54; _typed_elapsed_time(store_lsqr_f32[ws_ptr])
  elseif k == 0x55; _typed_elapsed_time(store_lsqr_f64[ws_ptr])
  elseif k == 0x56; _typed_elapsed_time(store_lsqr_cf32[ws_ptr])
  elseif k == 0x57; _typed_elapsed_time(store_lsqr_cf64[ws_ptr])
  elseif k == 0x58; _typed_elapsed_time(store_lsmr_f32[ws_ptr])
  elseif k == 0x59; _typed_elapsed_time(store_lsmr_f64[ws_ptr])
  elseif k == 0x5a; _typed_elapsed_time(store_lsmr_cf32[ws_ptr])
  elseif k == 0x5b; _typed_elapsed_time(store_lsmr_cf64[ws_ptr])
  elseif k == 0x5c; _typed_elapsed_time(store_usymlqr_f32[ws_ptr])
  elseif k == 0x5d; _typed_elapsed_time(store_usymlqr_f64[ws_ptr])
  elseif k == 0x5e; _typed_elapsed_time(store_usymlqr_cf32[ws_ptr])
  elseif k == 0x5f; _typed_elapsed_time(store_usymlqr_cf64[ws_ptr])
  elseif k == 0x60; _typed_elapsed_time(store_cgls_f32[ws_ptr])
  elseif k == 0x61; _typed_elapsed_time(store_cgls_f64[ws_ptr])
  elseif k == 0x62; _typed_elapsed_time(store_cgls_cf32[ws_ptr])
  elseif k == 0x63; _typed_elapsed_time(store_cgls_cf64[ws_ptr])
  elseif k == 0x64; _typed_elapsed_time(store_crls_f32[ws_ptr])
  elseif k == 0x65; _typed_elapsed_time(store_crls_f64[ws_ptr])
  elseif k == 0x66; _typed_elapsed_time(store_crls_cf32[ws_ptr])
  elseif k == 0x67; _typed_elapsed_time(store_crls_cf64[ws_ptr])
  elseif k == 0x68; _typed_elapsed_time(store_cgne_f32[ws_ptr])
  elseif k == 0x69; _typed_elapsed_time(store_cgne_f64[ws_ptr])
  elseif k == 0x6a; _typed_elapsed_time(store_cgne_cf32[ws_ptr])
  elseif k == 0x6b; _typed_elapsed_time(store_cgne_cf64[ws_ptr])
  elseif k == 0x6c; _typed_elapsed_time(store_crmr_f32[ws_ptr])
  elseif k == 0x6d; _typed_elapsed_time(store_crmr_f64[ws_ptr])
  elseif k == 0x6e; _typed_elapsed_time(store_crmr_cf32[ws_ptr])
  elseif k == 0x6f; _typed_elapsed_time(store_crmr_cf64[ws_ptr])
  elseif k == 0x70; _typed_elapsed_time(store_craig_f32[ws_ptr])
  elseif k == 0x71; _typed_elapsed_time(store_craig_f64[ws_ptr])
  elseif k == 0x72; _typed_elapsed_time(store_craig_cf32[ws_ptr])
  elseif k == 0x73; _typed_elapsed_time(store_craig_cf64[ws_ptr])
  elseif k == 0x74; _typed_elapsed_time(store_craigmr_f32[ws_ptr])
  elseif k == 0x75; _typed_elapsed_time(store_craigmr_f64[ws_ptr])
  elseif k == 0x76; _typed_elapsed_time(store_craigmr_cf32[ws_ptr])
  elseif k == 0x77; _typed_elapsed_time(store_craigmr_cf64[ws_ptr])
  elseif k == 0x78; _typed_elapsed_time(store_lnlq_f32[ws_ptr])
  elseif k == 0x79; _typed_elapsed_time(store_lnlq_f64[ws_ptr])
  elseif k == 0x7a; _typed_elapsed_time(store_lnlq_cf32[ws_ptr])
  elseif k == 0x7b; _typed_elapsed_time(store_lnlq_cf64[ws_ptr])
  elseif k == 0x7c; _typed_elapsed_time(store_gpmr_f32[ws_ptr])
  elseif k == 0x7d; _typed_elapsed_time(store_gpmr_f64[ws_ptr])
  elseif k == 0x7e; _typed_elapsed_time(store_gpmr_cf32[ws_ptr])
  elseif k == 0x7f; _typed_elapsed_time(store_gpmr_cf64[ws_ptr])
  elseif k == 0x80; _typed_elapsed_time(store_car_f32[ws_ptr])
  elseif k == 0x81; _typed_elapsed_time(store_car_f64[ws_ptr])
  elseif k == 0x82; _typed_elapsed_time(store_car_cf32[ws_ptr])
  elseif k == 0x83; _typed_elapsed_time(store_car_cf64[ws_ptr])
  elseif k == 0x84; _typed_elapsed_time(store_minares_f32[ws_ptr])
  elseif k == 0x85; _typed_elapsed_time(store_minares_f64[ws_ptr])
  elseif k == 0x86; _typed_elapsed_time(store_minares_cf32[ws_ptr])
  elseif k == 0x87; _typed_elapsed_time(store_minares_cf64[ws_ptr])
  else; Cdouble(-1.0); end
end

function _do_get_x!(ws_ptr :: Ptr{Cvoid}, x_ptr :: Ptr{Cvoid}, n :: Cint)
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_get_x!(store_cg_f32[ws_ptr], x_ptr, n)
  elseif k == 0x01; _typed_get_x!(store_cg_f64[ws_ptr], x_ptr, n)
  elseif k == 0x02; _typed_get_x!(store_cg_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x03; _typed_get_x!(store_cg_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x04; _typed_get_x!(store_cr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x05; _typed_get_x!(store_cr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x06; _typed_get_x!(store_cr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x07; _typed_get_x!(store_cr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x08; _typed_get_x!(store_symmlq_f32[ws_ptr], x_ptr, n)
  elseif k == 0x09; _typed_get_x!(store_symmlq_f64[ws_ptr], x_ptr, n)
  elseif k == 0x0a; _typed_get_x!(store_symmlq_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x0b; _typed_get_x!(store_symmlq_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x0c; _typed_get_x!(store_minres_f32[ws_ptr], x_ptr, n)
  elseif k == 0x0d; _typed_get_x!(store_minres_f64[ws_ptr], x_ptr, n)
  elseif k == 0x0e; _typed_get_x!(store_minres_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x0f; _typed_get_x!(store_minres_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x10; _typed_get_x!(store_minres_qlp_f32[ws_ptr], x_ptr, n)
  elseif k == 0x11; _typed_get_x!(store_minres_qlp_f64[ws_ptr], x_ptr, n)
  elseif k == 0x12; _typed_get_x!(store_minres_qlp_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x13; _typed_get_x!(store_minres_qlp_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x14; _typed_get_x!(store_diom_f32[ws_ptr], x_ptr, n)
  elseif k == 0x15; _typed_get_x!(store_diom_f64[ws_ptr], x_ptr, n)
  elseif k == 0x16; _typed_get_x!(store_diom_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x17; _typed_get_x!(store_diom_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x18; _typed_get_x!(store_dqgmres_f32[ws_ptr], x_ptr, n)
  elseif k == 0x19; _typed_get_x!(store_dqgmres_f64[ws_ptr], x_ptr, n)
  elseif k == 0x1a; _typed_get_x!(store_dqgmres_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x1b; _typed_get_x!(store_dqgmres_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x1c; _typed_get_x!(store_fom_f32[ws_ptr], x_ptr, n)
  elseif k == 0x1d; _typed_get_x!(store_fom_f64[ws_ptr], x_ptr, n)
  elseif k == 0x1e; _typed_get_x!(store_fom_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x1f; _typed_get_x!(store_fom_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x20; _typed_get_x!(store_gmres_f32[ws_ptr], x_ptr, n)
  elseif k == 0x21; _typed_get_x!(store_gmres_f64[ws_ptr], x_ptr, n)
  elseif k == 0x22; _typed_get_x!(store_gmres_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x23; _typed_get_x!(store_gmres_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x24; _typed_get_x!(store_fgmres_f32[ws_ptr], x_ptr, n)
  elseif k == 0x25; _typed_get_x!(store_fgmres_f64[ws_ptr], x_ptr, n)
  elseif k == 0x26; _typed_get_x!(store_fgmres_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x27; _typed_get_x!(store_fgmres_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x28; _typed_get_x!(store_bicgstab_f32[ws_ptr], x_ptr, n)
  elseif k == 0x29; _typed_get_x!(store_bicgstab_f64[ws_ptr], x_ptr, n)
  elseif k == 0x2a; _typed_get_x!(store_bicgstab_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x2b; _typed_get_x!(store_bicgstab_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x2c; _typed_get_x!(store_cgs_f32[ws_ptr], x_ptr, n)
  elseif k == 0x2d; _typed_get_x!(store_cgs_f64[ws_ptr], x_ptr, n)
  elseif k == 0x2e; _typed_get_x!(store_cgs_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x2f; _typed_get_x!(store_cgs_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x30; _typed_get_x!(store_bilq_f32[ws_ptr], x_ptr, n)
  elseif k == 0x31; _typed_get_x!(store_bilq_f64[ws_ptr], x_ptr, n)
  elseif k == 0x32; _typed_get_x!(store_bilq_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x33; _typed_get_x!(store_bilq_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x34; _typed_get_x!(store_qmr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x35; _typed_get_x!(store_qmr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x36; _typed_get_x!(store_qmr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x37; _typed_get_x!(store_qmr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x38; _typed_get_x!(store_usymlq_f32[ws_ptr], x_ptr, n)
  elseif k == 0x39; _typed_get_x!(store_usymlq_f64[ws_ptr], x_ptr, n)
  elseif k == 0x3a; _typed_get_x!(store_usymlq_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x3b; _typed_get_x!(store_usymlq_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x3c; _typed_get_x!(store_usymqr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x3d; _typed_get_x!(store_usymqr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x3e; _typed_get_x!(store_usymqr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x3f; _typed_get_x!(store_usymqr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x40; _typed_get_x!(store_tricg_f32[ws_ptr], x_ptr, n)
  elseif k == 0x41; _typed_get_x!(store_tricg_f64[ws_ptr], x_ptr, n)
  elseif k == 0x42; _typed_get_x!(store_tricg_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x43; _typed_get_x!(store_tricg_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x44; _typed_get_x!(store_trimr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x45; _typed_get_x!(store_trimr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x46; _typed_get_x!(store_trimr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x47; _typed_get_x!(store_trimr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x48; _typed_get_x!(store_trilqr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x49; _typed_get_x!(store_trilqr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x4a; _typed_get_x!(store_trilqr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x4b; _typed_get_x!(store_trilqr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x4c; _typed_get_x!(store_bilqr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x4d; _typed_get_x!(store_bilqr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x4e; _typed_get_x!(store_bilqr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x4f; _typed_get_x!(store_bilqr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x50; _typed_get_x!(store_lslq_f32[ws_ptr], x_ptr, n)
  elseif k == 0x51; _typed_get_x!(store_lslq_f64[ws_ptr], x_ptr, n)
  elseif k == 0x52; _typed_get_x!(store_lslq_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x53; _typed_get_x!(store_lslq_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x54; _typed_get_x!(store_lsqr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x55; _typed_get_x!(store_lsqr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x56; _typed_get_x!(store_lsqr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x57; _typed_get_x!(store_lsqr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x58; _typed_get_x!(store_lsmr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x59; _typed_get_x!(store_lsmr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x5a; _typed_get_x!(store_lsmr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x5b; _typed_get_x!(store_lsmr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x5c; _typed_get_x!(store_usymlqr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x5d; _typed_get_x!(store_usymlqr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x5e; _typed_get_x!(store_usymlqr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x5f; _typed_get_x!(store_usymlqr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x60; _typed_get_x!(store_cgls_f32[ws_ptr], x_ptr, n)
  elseif k == 0x61; _typed_get_x!(store_cgls_f64[ws_ptr], x_ptr, n)
  elseif k == 0x62; _typed_get_x!(store_cgls_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x63; _typed_get_x!(store_cgls_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x64; _typed_get_x!(store_crls_f32[ws_ptr], x_ptr, n)
  elseif k == 0x65; _typed_get_x!(store_crls_f64[ws_ptr], x_ptr, n)
  elseif k == 0x66; _typed_get_x!(store_crls_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x67; _typed_get_x!(store_crls_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x68; _typed_get_x!(store_cgne_f32[ws_ptr], x_ptr, n)
  elseif k == 0x69; _typed_get_x!(store_cgne_f64[ws_ptr], x_ptr, n)
  elseif k == 0x6a; _typed_get_x!(store_cgne_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x6b; _typed_get_x!(store_cgne_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x6c; _typed_get_x!(store_crmr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x6d; _typed_get_x!(store_crmr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x6e; _typed_get_x!(store_crmr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x6f; _typed_get_x!(store_crmr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x70; _typed_get_x!(store_craig_f32[ws_ptr], x_ptr, n)
  elseif k == 0x71; _typed_get_x!(store_craig_f64[ws_ptr], x_ptr, n)
  elseif k == 0x72; _typed_get_x!(store_craig_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x73; _typed_get_x!(store_craig_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x74; _typed_get_x!(store_craigmr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x75; _typed_get_x!(store_craigmr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x76; _typed_get_x!(store_craigmr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x77; _typed_get_x!(store_craigmr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x78; _typed_get_x!(store_lnlq_f32[ws_ptr], x_ptr, n)
  elseif k == 0x79; _typed_get_x!(store_lnlq_f64[ws_ptr], x_ptr, n)
  elseif k == 0x7a; _typed_get_x!(store_lnlq_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x7b; _typed_get_x!(store_lnlq_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x7c; _typed_get_x!(store_gpmr_f32[ws_ptr], x_ptr, n)
  elseif k == 0x7d; _typed_get_x!(store_gpmr_f64[ws_ptr], x_ptr, n)
  elseif k == 0x7e; _typed_get_x!(store_gpmr_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x7f; _typed_get_x!(store_gpmr_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x80; _typed_get_x!(store_car_f32[ws_ptr], x_ptr, n)
  elseif k == 0x81; _typed_get_x!(store_car_f64[ws_ptr], x_ptr, n)
  elseif k == 0x82; _typed_get_x!(store_car_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x83; _typed_get_x!(store_car_cf64[ws_ptr], x_ptr, n)
  elseif k == 0x84; _typed_get_x!(store_minares_f32[ws_ptr], x_ptr, n)
  elseif k == 0x85; _typed_get_x!(store_minares_f64[ws_ptr], x_ptr, n)
  elseif k == 0x86; _typed_get_x!(store_minares_cf32[ws_ptr], x_ptr, n)
  elseif k == 0x87; _typed_get_x!(store_minares_cf64[ws_ptr], x_ptr, n)
  else; Cint(-1); end
end

function _do_get_y!(ws_ptr :: Ptr{Cvoid}, y_ptr :: Ptr{Cvoid}, m :: Cint)
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_get_y!(store_cg_f32[ws_ptr], y_ptr, m)
  elseif k == 0x01; _typed_get_y!(store_cg_f64[ws_ptr], y_ptr, m)
  elseif k == 0x02; _typed_get_y!(store_cg_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x03; _typed_get_y!(store_cg_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x04; _typed_get_y!(store_cr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x05; _typed_get_y!(store_cr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x06; _typed_get_y!(store_cr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x07; _typed_get_y!(store_cr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x08; _typed_get_y!(store_symmlq_f32[ws_ptr], y_ptr, m)
  elseif k == 0x09; _typed_get_y!(store_symmlq_f64[ws_ptr], y_ptr, m)
  elseif k == 0x0a; _typed_get_y!(store_symmlq_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x0b; _typed_get_y!(store_symmlq_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x0c; _typed_get_y!(store_minres_f32[ws_ptr], y_ptr, m)
  elseif k == 0x0d; _typed_get_y!(store_minres_f64[ws_ptr], y_ptr, m)
  elseif k == 0x0e; _typed_get_y!(store_minres_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x0f; _typed_get_y!(store_minres_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x10; _typed_get_y!(store_minres_qlp_f32[ws_ptr], y_ptr, m)
  elseif k == 0x11; _typed_get_y!(store_minres_qlp_f64[ws_ptr], y_ptr, m)
  elseif k == 0x12; _typed_get_y!(store_minres_qlp_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x13; _typed_get_y!(store_minres_qlp_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x14; _typed_get_y!(store_diom_f32[ws_ptr], y_ptr, m)
  elseif k == 0x15; _typed_get_y!(store_diom_f64[ws_ptr], y_ptr, m)
  elseif k == 0x16; _typed_get_y!(store_diom_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x17; _typed_get_y!(store_diom_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x18; _typed_get_y!(store_dqgmres_f32[ws_ptr], y_ptr, m)
  elseif k == 0x19; _typed_get_y!(store_dqgmres_f64[ws_ptr], y_ptr, m)
  elseif k == 0x1a; _typed_get_y!(store_dqgmres_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x1b; _typed_get_y!(store_dqgmres_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x1c; _typed_get_y!(store_fom_f32[ws_ptr], y_ptr, m)
  elseif k == 0x1d; _typed_get_y!(store_fom_f64[ws_ptr], y_ptr, m)
  elseif k == 0x1e; _typed_get_y!(store_fom_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x1f; _typed_get_y!(store_fom_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x20; _typed_get_y!(store_gmres_f32[ws_ptr], y_ptr, m)
  elseif k == 0x21; _typed_get_y!(store_gmres_f64[ws_ptr], y_ptr, m)
  elseif k == 0x22; _typed_get_y!(store_gmres_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x23; _typed_get_y!(store_gmres_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x24; _typed_get_y!(store_fgmres_f32[ws_ptr], y_ptr, m)
  elseif k == 0x25; _typed_get_y!(store_fgmres_f64[ws_ptr], y_ptr, m)
  elseif k == 0x26; _typed_get_y!(store_fgmres_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x27; _typed_get_y!(store_fgmres_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x28; _typed_get_y!(store_bicgstab_f32[ws_ptr], y_ptr, m)
  elseif k == 0x29; _typed_get_y!(store_bicgstab_f64[ws_ptr], y_ptr, m)
  elseif k == 0x2a; _typed_get_y!(store_bicgstab_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x2b; _typed_get_y!(store_bicgstab_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x2c; _typed_get_y!(store_cgs_f32[ws_ptr], y_ptr, m)
  elseif k == 0x2d; _typed_get_y!(store_cgs_f64[ws_ptr], y_ptr, m)
  elseif k == 0x2e; _typed_get_y!(store_cgs_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x2f; _typed_get_y!(store_cgs_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x30; _typed_get_y!(store_bilq_f32[ws_ptr], y_ptr, m)
  elseif k == 0x31; _typed_get_y!(store_bilq_f64[ws_ptr], y_ptr, m)
  elseif k == 0x32; _typed_get_y!(store_bilq_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x33; _typed_get_y!(store_bilq_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x34; _typed_get_y!(store_qmr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x35; _typed_get_y!(store_qmr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x36; _typed_get_y!(store_qmr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x37; _typed_get_y!(store_qmr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x38; _typed_get_y!(store_usymlq_f32[ws_ptr], y_ptr, m)
  elseif k == 0x39; _typed_get_y!(store_usymlq_f64[ws_ptr], y_ptr, m)
  elseif k == 0x3a; _typed_get_y!(store_usymlq_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x3b; _typed_get_y!(store_usymlq_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x3c; _typed_get_y!(store_usymqr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x3d; _typed_get_y!(store_usymqr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x3e; _typed_get_y!(store_usymqr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x3f; _typed_get_y!(store_usymqr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x40; _typed_get_y!(store_tricg_f32[ws_ptr], y_ptr, m)
  elseif k == 0x41; _typed_get_y!(store_tricg_f64[ws_ptr], y_ptr, m)
  elseif k == 0x42; _typed_get_y!(store_tricg_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x43; _typed_get_y!(store_tricg_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x44; _typed_get_y!(store_trimr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x45; _typed_get_y!(store_trimr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x46; _typed_get_y!(store_trimr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x47; _typed_get_y!(store_trimr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x48; _typed_get_y!(store_trilqr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x49; _typed_get_y!(store_trilqr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x4a; _typed_get_y!(store_trilqr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x4b; _typed_get_y!(store_trilqr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x4c; _typed_get_y!(store_bilqr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x4d; _typed_get_y!(store_bilqr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x4e; _typed_get_y!(store_bilqr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x4f; _typed_get_y!(store_bilqr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x50; _typed_get_y!(store_lslq_f32[ws_ptr], y_ptr, m)
  elseif k == 0x51; _typed_get_y!(store_lslq_f64[ws_ptr], y_ptr, m)
  elseif k == 0x52; _typed_get_y!(store_lslq_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x53; _typed_get_y!(store_lslq_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x54; _typed_get_y!(store_lsqr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x55; _typed_get_y!(store_lsqr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x56; _typed_get_y!(store_lsqr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x57; _typed_get_y!(store_lsqr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x58; _typed_get_y!(store_lsmr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x59; _typed_get_y!(store_lsmr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x5a; _typed_get_y!(store_lsmr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x5b; _typed_get_y!(store_lsmr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x5c; _typed_get_y!(store_usymlqr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x5d; _typed_get_y!(store_usymlqr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x5e; _typed_get_y!(store_usymlqr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x5f; _typed_get_y!(store_usymlqr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x60; _typed_get_y!(store_cgls_f32[ws_ptr], y_ptr, m)
  elseif k == 0x61; _typed_get_y!(store_cgls_f64[ws_ptr], y_ptr, m)
  elseif k == 0x62; _typed_get_y!(store_cgls_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x63; _typed_get_y!(store_cgls_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x64; _typed_get_y!(store_crls_f32[ws_ptr], y_ptr, m)
  elseif k == 0x65; _typed_get_y!(store_crls_f64[ws_ptr], y_ptr, m)
  elseif k == 0x66; _typed_get_y!(store_crls_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x67; _typed_get_y!(store_crls_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x68; _typed_get_y!(store_cgne_f32[ws_ptr], y_ptr, m)
  elseif k == 0x69; _typed_get_y!(store_cgne_f64[ws_ptr], y_ptr, m)
  elseif k == 0x6a; _typed_get_y!(store_cgne_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x6b; _typed_get_y!(store_cgne_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x6c; _typed_get_y!(store_crmr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x6d; _typed_get_y!(store_crmr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x6e; _typed_get_y!(store_crmr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x6f; _typed_get_y!(store_crmr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x70; _typed_get_y!(store_craig_f32[ws_ptr], y_ptr, m)
  elseif k == 0x71; _typed_get_y!(store_craig_f64[ws_ptr], y_ptr, m)
  elseif k == 0x72; _typed_get_y!(store_craig_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x73; _typed_get_y!(store_craig_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x74; _typed_get_y!(store_craigmr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x75; _typed_get_y!(store_craigmr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x76; _typed_get_y!(store_craigmr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x77; _typed_get_y!(store_craigmr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x78; _typed_get_y!(store_lnlq_f32[ws_ptr], y_ptr, m)
  elseif k == 0x79; _typed_get_y!(store_lnlq_f64[ws_ptr], y_ptr, m)
  elseif k == 0x7a; _typed_get_y!(store_lnlq_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x7b; _typed_get_y!(store_lnlq_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x7c; _typed_get_y!(store_gpmr_f32[ws_ptr], y_ptr, m)
  elseif k == 0x7d; _typed_get_y!(store_gpmr_f64[ws_ptr], y_ptr, m)
  elseif k == 0x7e; _typed_get_y!(store_gpmr_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x7f; _typed_get_y!(store_gpmr_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x80; _typed_get_y!(store_car_f32[ws_ptr], y_ptr, m)
  elseif k == 0x81; _typed_get_y!(store_car_f64[ws_ptr], y_ptr, m)
  elseif k == 0x82; _typed_get_y!(store_car_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x83; _typed_get_y!(store_car_cf64[ws_ptr], y_ptr, m)
  elseif k == 0x84; _typed_get_y!(store_minares_f32[ws_ptr], y_ptr, m)
  elseif k == 0x85; _typed_get_y!(store_minares_f64[ws_ptr], y_ptr, m)
  elseif k == 0x86; _typed_get_y!(store_minares_cf32[ws_ptr], y_ptr, m)
  elseif k == 0x87; _typed_get_y!(store_minares_cf64[ws_ptr], y_ptr, m)
  else; Cint(-1); end
end

function _do_warm_start!(ws_ptr :: Ptr{Cvoid}, x0_ptr :: Ptr{Cvoid}, n :: Cint)
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_warm_start!(store_cg_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x01; _typed_warm_start!(store_cg_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x02; _typed_warm_start!(store_cg_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x03; _typed_warm_start!(store_cg_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x04; _typed_warm_start!(store_cr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x05; _typed_warm_start!(store_cr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x06; _typed_warm_start!(store_cr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x07; _typed_warm_start!(store_cr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x08; _typed_warm_start!(store_symmlq_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x09; _typed_warm_start!(store_symmlq_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x0a; _typed_warm_start!(store_symmlq_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x0b; _typed_warm_start!(store_symmlq_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x0c; _typed_warm_start!(store_minres_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x0d; _typed_warm_start!(store_minres_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x0e; _typed_warm_start!(store_minres_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x0f; _typed_warm_start!(store_minres_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x10; _typed_warm_start!(store_minres_qlp_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x11; _typed_warm_start!(store_minres_qlp_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x12; _typed_warm_start!(store_minres_qlp_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x13; _typed_warm_start!(store_minres_qlp_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x14; _typed_warm_start!(store_diom_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x15; _typed_warm_start!(store_diom_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x16; _typed_warm_start!(store_diom_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x17; _typed_warm_start!(store_diom_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x18; _typed_warm_start!(store_dqgmres_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x19; _typed_warm_start!(store_dqgmres_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x1a; _typed_warm_start!(store_dqgmres_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x1b; _typed_warm_start!(store_dqgmres_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x1c; _typed_warm_start!(store_fom_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x1d; _typed_warm_start!(store_fom_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x1e; _typed_warm_start!(store_fom_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x1f; _typed_warm_start!(store_fom_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x20; _typed_warm_start!(store_gmres_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x21; _typed_warm_start!(store_gmres_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x22; _typed_warm_start!(store_gmres_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x23; _typed_warm_start!(store_gmres_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x24; _typed_warm_start!(store_fgmres_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x25; _typed_warm_start!(store_fgmres_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x26; _typed_warm_start!(store_fgmres_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x27; _typed_warm_start!(store_fgmres_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x28; _typed_warm_start!(store_bicgstab_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x29; _typed_warm_start!(store_bicgstab_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x2a; _typed_warm_start!(store_bicgstab_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x2b; _typed_warm_start!(store_bicgstab_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x2c; _typed_warm_start!(store_cgs_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x2d; _typed_warm_start!(store_cgs_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x2e; _typed_warm_start!(store_cgs_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x2f; _typed_warm_start!(store_cgs_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x30; _typed_warm_start!(store_bilq_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x31; _typed_warm_start!(store_bilq_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x32; _typed_warm_start!(store_bilq_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x33; _typed_warm_start!(store_bilq_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x34; _typed_warm_start!(store_qmr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x35; _typed_warm_start!(store_qmr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x36; _typed_warm_start!(store_qmr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x37; _typed_warm_start!(store_qmr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x38; _typed_warm_start!(store_usymlq_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x39; _typed_warm_start!(store_usymlq_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x3a; _typed_warm_start!(store_usymlq_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x3b; _typed_warm_start!(store_usymlq_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x3c; _typed_warm_start!(store_usymqr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x3d; _typed_warm_start!(store_usymqr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x3e; _typed_warm_start!(store_usymqr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x3f; _typed_warm_start!(store_usymqr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x40; _typed_warm_start!(store_tricg_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x41; _typed_warm_start!(store_tricg_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x42; _typed_warm_start!(store_tricg_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x43; _typed_warm_start!(store_tricg_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x44; _typed_warm_start!(store_trimr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x45; _typed_warm_start!(store_trimr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x46; _typed_warm_start!(store_trimr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x47; _typed_warm_start!(store_trimr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x48; _typed_warm_start!(store_trilqr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x49; _typed_warm_start!(store_trilqr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x4a; _typed_warm_start!(store_trilqr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x4b; _typed_warm_start!(store_trilqr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x4c; _typed_warm_start!(store_bilqr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x4d; _typed_warm_start!(store_bilqr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x4e; _typed_warm_start!(store_bilqr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x4f; _typed_warm_start!(store_bilqr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x50; _typed_warm_start!(store_lslq_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x51; _typed_warm_start!(store_lslq_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x52; _typed_warm_start!(store_lslq_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x53; _typed_warm_start!(store_lslq_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x54; _typed_warm_start!(store_lsqr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x55; _typed_warm_start!(store_lsqr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x56; _typed_warm_start!(store_lsqr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x57; _typed_warm_start!(store_lsqr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x58; _typed_warm_start!(store_lsmr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x59; _typed_warm_start!(store_lsmr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x5a; _typed_warm_start!(store_lsmr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x5b; _typed_warm_start!(store_lsmr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x5c; _typed_warm_start!(store_usymlqr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x5d; _typed_warm_start!(store_usymlqr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x5e; _typed_warm_start!(store_usymlqr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x5f; _typed_warm_start!(store_usymlqr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x60; _typed_warm_start!(store_cgls_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x61; _typed_warm_start!(store_cgls_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x62; _typed_warm_start!(store_cgls_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x63; _typed_warm_start!(store_cgls_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x64; _typed_warm_start!(store_crls_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x65; _typed_warm_start!(store_crls_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x66; _typed_warm_start!(store_crls_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x67; _typed_warm_start!(store_crls_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x68; _typed_warm_start!(store_cgne_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x69; _typed_warm_start!(store_cgne_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x6a; _typed_warm_start!(store_cgne_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x6b; _typed_warm_start!(store_cgne_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x6c; _typed_warm_start!(store_crmr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x6d; _typed_warm_start!(store_crmr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x6e; _typed_warm_start!(store_crmr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x6f; _typed_warm_start!(store_crmr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x70; _typed_warm_start!(store_craig_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x71; _typed_warm_start!(store_craig_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x72; _typed_warm_start!(store_craig_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x73; _typed_warm_start!(store_craig_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x74; _typed_warm_start!(store_craigmr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x75; _typed_warm_start!(store_craigmr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x76; _typed_warm_start!(store_craigmr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x77; _typed_warm_start!(store_craigmr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x78; _typed_warm_start!(store_lnlq_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x79; _typed_warm_start!(store_lnlq_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x7a; _typed_warm_start!(store_lnlq_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x7b; _typed_warm_start!(store_lnlq_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x7c; _typed_warm_start!(store_gpmr_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x7d; _typed_warm_start!(store_gpmr_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x7e; _typed_warm_start!(store_gpmr_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x7f; _typed_warm_start!(store_gpmr_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x80; _typed_warm_start!(store_car_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x81; _typed_warm_start!(store_car_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x82; _typed_warm_start!(store_car_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x83; _typed_warm_start!(store_car_cf64[ws_ptr], x0_ptr, n)
  elseif k == 0x84; _typed_warm_start!(store_minares_f32[ws_ptr], x0_ptr, n)
  elseif k == 0x85; _typed_warm_start!(store_minares_f64[ws_ptr], x0_ptr, n)
  elseif k == 0x86; _typed_warm_start!(store_minares_cf32[ws_ptr], x0_ptr, n)
  elseif k == 0x87; _typed_warm_start!(store_minares_cf64[ws_ptr], x0_ptr, n)
  else; Cint(-1); end
end

function _do_warm_start2!(ws_ptr :: Ptr{Cvoid}, x0_ptr :: Ptr{Cvoid}, y0_ptr :: Ptr{Cvoid}, nx :: Cint, ny :: Cint)
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_warm_start2!(store_cg_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x01; _typed_warm_start2!(store_cg_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x02; _typed_warm_start2!(store_cg_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x03; _typed_warm_start2!(store_cg_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x04; _typed_warm_start2!(store_cr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x05; _typed_warm_start2!(store_cr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x06; _typed_warm_start2!(store_cr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x07; _typed_warm_start2!(store_cr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x08; _typed_warm_start2!(store_symmlq_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x09; _typed_warm_start2!(store_symmlq_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0a; _typed_warm_start2!(store_symmlq_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0b; _typed_warm_start2!(store_symmlq_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0c; _typed_warm_start2!(store_minres_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0d; _typed_warm_start2!(store_minres_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0e; _typed_warm_start2!(store_minres_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x0f; _typed_warm_start2!(store_minres_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x10; _typed_warm_start2!(store_minres_qlp_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x11; _typed_warm_start2!(store_minres_qlp_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x12; _typed_warm_start2!(store_minres_qlp_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x13; _typed_warm_start2!(store_minres_qlp_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x14; _typed_warm_start2!(store_diom_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x15; _typed_warm_start2!(store_diom_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x16; _typed_warm_start2!(store_diom_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x17; _typed_warm_start2!(store_diom_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x18; _typed_warm_start2!(store_dqgmres_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x19; _typed_warm_start2!(store_dqgmres_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1a; _typed_warm_start2!(store_dqgmres_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1b; _typed_warm_start2!(store_dqgmres_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1c; _typed_warm_start2!(store_fom_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1d; _typed_warm_start2!(store_fom_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1e; _typed_warm_start2!(store_fom_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x1f; _typed_warm_start2!(store_fom_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x20; _typed_warm_start2!(store_gmres_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x21; _typed_warm_start2!(store_gmres_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x22; _typed_warm_start2!(store_gmres_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x23; _typed_warm_start2!(store_gmres_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x24; _typed_warm_start2!(store_fgmres_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x25; _typed_warm_start2!(store_fgmres_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x26; _typed_warm_start2!(store_fgmres_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x27; _typed_warm_start2!(store_fgmres_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x28; _typed_warm_start2!(store_bicgstab_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x29; _typed_warm_start2!(store_bicgstab_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2a; _typed_warm_start2!(store_bicgstab_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2b; _typed_warm_start2!(store_bicgstab_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2c; _typed_warm_start2!(store_cgs_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2d; _typed_warm_start2!(store_cgs_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2e; _typed_warm_start2!(store_cgs_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x2f; _typed_warm_start2!(store_cgs_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x30; _typed_warm_start2!(store_bilq_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x31; _typed_warm_start2!(store_bilq_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x32; _typed_warm_start2!(store_bilq_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x33; _typed_warm_start2!(store_bilq_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x34; _typed_warm_start2!(store_qmr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x35; _typed_warm_start2!(store_qmr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x36; _typed_warm_start2!(store_qmr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x37; _typed_warm_start2!(store_qmr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x38; _typed_warm_start2!(store_usymlq_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x39; _typed_warm_start2!(store_usymlq_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3a; _typed_warm_start2!(store_usymlq_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3b; _typed_warm_start2!(store_usymlq_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3c; _typed_warm_start2!(store_usymqr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3d; _typed_warm_start2!(store_usymqr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3e; _typed_warm_start2!(store_usymqr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x3f; _typed_warm_start2!(store_usymqr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x40; _typed_warm_start2!(store_tricg_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x41; _typed_warm_start2!(store_tricg_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x42; _typed_warm_start2!(store_tricg_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x43; _typed_warm_start2!(store_tricg_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x44; _typed_warm_start2!(store_trimr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x45; _typed_warm_start2!(store_trimr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x46; _typed_warm_start2!(store_trimr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x47; _typed_warm_start2!(store_trimr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x48; _typed_warm_start2!(store_trilqr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x49; _typed_warm_start2!(store_trilqr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4a; _typed_warm_start2!(store_trilqr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4b; _typed_warm_start2!(store_trilqr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4c; _typed_warm_start2!(store_bilqr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4d; _typed_warm_start2!(store_bilqr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4e; _typed_warm_start2!(store_bilqr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x4f; _typed_warm_start2!(store_bilqr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x50; _typed_warm_start2!(store_lslq_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x51; _typed_warm_start2!(store_lslq_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x52; _typed_warm_start2!(store_lslq_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x53; _typed_warm_start2!(store_lslq_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x54; _typed_warm_start2!(store_lsqr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x55; _typed_warm_start2!(store_lsqr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x56; _typed_warm_start2!(store_lsqr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x57; _typed_warm_start2!(store_lsqr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x58; _typed_warm_start2!(store_lsmr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x59; _typed_warm_start2!(store_lsmr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5a; _typed_warm_start2!(store_lsmr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5b; _typed_warm_start2!(store_lsmr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5c; _typed_warm_start2!(store_usymlqr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5d; _typed_warm_start2!(store_usymlqr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5e; _typed_warm_start2!(store_usymlqr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x5f; _typed_warm_start2!(store_usymlqr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x60; _typed_warm_start2!(store_cgls_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x61; _typed_warm_start2!(store_cgls_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x62; _typed_warm_start2!(store_cgls_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x63; _typed_warm_start2!(store_cgls_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x64; _typed_warm_start2!(store_crls_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x65; _typed_warm_start2!(store_crls_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x66; _typed_warm_start2!(store_crls_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x67; _typed_warm_start2!(store_crls_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x68; _typed_warm_start2!(store_cgne_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x69; _typed_warm_start2!(store_cgne_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6a; _typed_warm_start2!(store_cgne_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6b; _typed_warm_start2!(store_cgne_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6c; _typed_warm_start2!(store_crmr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6d; _typed_warm_start2!(store_crmr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6e; _typed_warm_start2!(store_crmr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x6f; _typed_warm_start2!(store_crmr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x70; _typed_warm_start2!(store_craig_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x71; _typed_warm_start2!(store_craig_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x72; _typed_warm_start2!(store_craig_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x73; _typed_warm_start2!(store_craig_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x74; _typed_warm_start2!(store_craigmr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x75; _typed_warm_start2!(store_craigmr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x76; _typed_warm_start2!(store_craigmr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x77; _typed_warm_start2!(store_craigmr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x78; _typed_warm_start2!(store_lnlq_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x79; _typed_warm_start2!(store_lnlq_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7a; _typed_warm_start2!(store_lnlq_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7b; _typed_warm_start2!(store_lnlq_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7c; _typed_warm_start2!(store_gpmr_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7d; _typed_warm_start2!(store_gpmr_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7e; _typed_warm_start2!(store_gpmr_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x7f; _typed_warm_start2!(store_gpmr_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x80; _typed_warm_start2!(store_car_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x81; _typed_warm_start2!(store_car_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x82; _typed_warm_start2!(store_car_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x83; _typed_warm_start2!(store_car_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x84; _typed_warm_start2!(store_minares_f32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x85; _typed_warm_start2!(store_minares_f64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x86; _typed_warm_start2!(store_minares_cf32[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  elseif k == 0x87; _typed_warm_start2!(store_minares_cf64[ws_ptr], x0_ptr, y0_ptr, nx, ny)
  else; Cint(-1); end
end

function _do_solve!(ws_ptr :: Ptr{Cvoid}, fptr_A :: Ptr{Cvoid}, fptr_At :: Ptr{Cvoid}, fptr_M :: Ptr{Cvoid}, fptr_N :: Ptr{Cvoid}, b_ptr :: Ptr{Cvoid}, c_ptr :: Ptr{Cvoid}, userdata :: Ptr{Cvoid}, opts_ptr :: Ptr{Cvoid})
  haskey(ws_key_store, ws_ptr) || return Cint(-1)
  opts = opts_ptr == C_NULL ? KrylovOptionsC(NaN, NaN, Cint(0), Cint(0), 0.0, NaN, NaN, NaN, 0.0, Cint(0), Cint(0), Cint(0)) : unsafe_load(Ptr{KrylovOptionsC}(opts_ptr))
  k = ws_key_store[ws_ptr]
  if k == 0x00; _typed_solve_cg!(store_cg_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x01; _typed_solve_cg!(store_cg_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x02; _typed_solve_cg!(store_cg_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x03; _typed_solve_cg!(store_cg_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x04; _typed_solve_cg!(store_cr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x05; _typed_solve_cg!(store_cr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x06; _typed_solve_cg!(store_cr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x07; _typed_solve_cg!(store_cr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x08; _typed_solve_sym_lambda!(store_symmlq_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x09; _typed_solve_sym_lambda!(store_symmlq_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0a; _typed_solve_sym_lambda!(store_symmlq_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0b; _typed_solve_sym_lambda!(store_symmlq_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0c; _typed_solve_minres!(store_minres_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0d; _typed_solve_minres!(store_minres_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0e; _typed_solve_minres!(store_minres_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x0f; _typed_solve_minres!(store_minres_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x10; _typed_solve_minres!(store_minres_qlp_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x11; _typed_solve_minres!(store_minres_qlp_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x12; _typed_solve_minres!(store_minres_qlp_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x13; _typed_solve_minres!(store_minres_qlp_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x14; _typed_solve_mn_reorth!(store_diom_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x15; _typed_solve_mn_reorth!(store_diom_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x16; _typed_solve_mn_reorth!(store_diom_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x17; _typed_solve_mn_reorth!(store_diom_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x18; _typed_solve_mn_reorth!(store_dqgmres_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x19; _typed_solve_mn_reorth!(store_dqgmres_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1a; _typed_solve_mn_reorth!(store_dqgmres_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1b; _typed_solve_mn_reorth!(store_dqgmres_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1c; _typed_solve_gmres!(store_fom_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1d; _typed_solve_gmres!(store_fom_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1e; _typed_solve_gmres!(store_fom_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x1f; _typed_solve_gmres!(store_fom_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x20; _typed_solve_gmres!(store_gmres_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x21; _typed_solve_gmres!(store_gmres_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x22; _typed_solve_gmres!(store_gmres_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x23; _typed_solve_gmres!(store_gmres_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x24; _typed_solve_gmres!(store_fgmres_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x25; _typed_solve_gmres!(store_fgmres_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x26; _typed_solve_gmres!(store_fgmres_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x27; _typed_solve_gmres!(store_fgmres_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x28; _typed_solve_mn!(store_bicgstab_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x29; _typed_solve_mn!(store_bicgstab_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2a; _typed_solve_mn!(store_bicgstab_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2b; _typed_solve_mn!(store_bicgstab_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2c; _typed_solve_mn!(store_cgs_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2d; _typed_solve_mn!(store_cgs_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2e; _typed_solve_mn!(store_cgs_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x2f; _typed_solve_mn!(store_cgs_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x30; _typed_solve_mn!(store_bilq_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x31; _typed_solve_mn!(store_bilq_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x32; _typed_solve_mn!(store_bilq_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x33; _typed_solve_mn!(store_bilq_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x34; _typed_solve_mn!(store_qmr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x35; _typed_solve_mn!(store_qmr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x36; _typed_solve_mn!(store_qmr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x37; _typed_solve_mn!(store_qmr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x38; _typed_solve_two_rhs!(store_usymlq_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x39; _typed_solve_two_rhs!(store_usymlq_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3a; _typed_solve_two_rhs!(store_usymlq_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3b; _typed_solve_two_rhs!(store_usymlq_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3c; _typed_solve_two_rhs!(store_usymqr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3d; _typed_solve_two_rhs!(store_usymqr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3e; _typed_solve_two_rhs!(store_usymqr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x3f; _typed_solve_two_rhs!(store_usymqr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x40; _typed_solve_tau_nu!(store_tricg_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x41; _typed_solve_tau_nu!(store_tricg_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x42; _typed_solve_tau_nu!(store_tricg_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x43; _typed_solve_tau_nu!(store_tricg_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x44; _typed_solve_tau_nu!(store_trimr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x45; _typed_solve_tau_nu!(store_trimr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x46; _typed_solve_tau_nu!(store_trimr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x47; _typed_solve_tau_nu!(store_trimr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x48; _typed_solve_two_rhs!(store_trilqr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x49; _typed_solve_two_rhs!(store_trilqr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4a; _typed_solve_two_rhs!(store_trilqr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4b; _typed_solve_two_rhs!(store_trilqr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4c; _typed_solve_two_rhs!(store_bilqr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4d; _typed_solve_two_rhs!(store_bilqr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4e; _typed_solve_two_rhs!(store_bilqr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x4f; _typed_solve_two_rhs!(store_bilqr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x50; _typed_solve_ls_mn!(store_lslq_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x51; _typed_solve_ls_mn!(store_lslq_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x52; _typed_solve_ls_mn!(store_lslq_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x53; _typed_solve_ls_mn!(store_lslq_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x54; _typed_solve_ls_mn_radius!(store_lsqr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x55; _typed_solve_ls_mn_radius!(store_lsqr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x56; _typed_solve_ls_mn_radius!(store_lsqr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x57; _typed_solve_ls_mn_radius!(store_lsqr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x58; _typed_solve_ls_mn_radius!(store_lsmr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x59; _typed_solve_ls_mn_radius!(store_lsmr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5a; _typed_solve_ls_mn_radius!(store_lsmr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5b; _typed_solve_ls_mn_radius!(store_lsmr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5c; _typed_solve_two_rhs!(store_usymlqr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5d; _typed_solve_two_rhs!(store_usymlqr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5e; _typed_solve_two_rhs!(store_usymlqr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x5f; _typed_solve_two_rhs!(store_usymlqr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x60; _typed_solve_ls_m_radius!(store_cgls_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x61; _typed_solve_ls_m_radius!(store_cgls_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x62; _typed_solve_ls_m_radius!(store_cgls_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x63; _typed_solve_ls_m_radius!(store_cgls_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x64; _typed_solve_ls_m_radius!(store_crls_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x65; _typed_solve_ls_m_radius!(store_crls_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x66; _typed_solve_ls_m_radius!(store_crls_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x67; _typed_solve_ls_m_radius!(store_crls_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x68; _typed_solve_ls_n!(store_cgne_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x69; _typed_solve_ls_n!(store_cgne_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6a; _typed_solve_ls_n!(store_cgne_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6b; _typed_solve_ls_n!(store_cgne_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6c; _typed_solve_ls_n!(store_crmr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6d; _typed_solve_ls_n!(store_crmr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6e; _typed_solve_ls_n!(store_crmr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x6f; _typed_solve_ls_n!(store_crmr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x70; _typed_solve_ls_mn!(store_craig_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x71; _typed_solve_ls_mn!(store_craig_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x72; _typed_solve_ls_mn!(store_craig_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x73; _typed_solve_ls_mn!(store_craig_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x74; _typed_solve_ls_mn!(store_craigmr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x75; _typed_solve_ls_mn!(store_craigmr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x76; _typed_solve_ls_mn!(store_craigmr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x77; _typed_solve_ls_mn!(store_craigmr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x78; _typed_solve_ls_mn!(store_lnlq_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x79; _typed_solve_ls_mn!(store_lnlq_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7a; _typed_solve_ls_mn!(store_lnlq_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7b; _typed_solve_ls_mn!(store_lnlq_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7c; _typed_solve_gpmr!(store_gpmr_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7d; _typed_solve_gpmr!(store_gpmr_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7e; _typed_solve_gpmr!(store_gpmr_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x7f; _typed_solve_gpmr!(store_gpmr_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x80; _typed_solve!(store_car_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x81; _typed_solve!(store_car_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x82; _typed_solve!(store_car_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x83; _typed_solve!(store_car_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x84; _typed_solve_sym_lambda!(store_minares_f32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x85; _typed_solve_sym_lambda!(store_minares_f64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x86; _typed_solve_sym_lambda!(store_minares_cf32[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  elseif k == 0x87; _typed_solve_sym_lambda!(store_minares_cf64[ws_ptr], fptr_A, fptr_At, fptr_M, fptr_N, b_ptr, c_ptr, userdata, opts)
  else; Cint(-1); end
end

function _do_free!(ws_ptr :: Ptr{Cvoid})
  haskey(ws_key_store, ws_ptr) || return Cint(1)
  k = ws_key_store[ws_ptr]
  delete!(ws_key_store, ws_ptr)
  if k == 0x00; delete!(store_cg_f32, ws_ptr)
  elseif k == 0x01; delete!(store_cg_f64, ws_ptr)
  elseif k == 0x02; delete!(store_cg_cf32, ws_ptr)
  elseif k == 0x03; delete!(store_cg_cf64, ws_ptr)
  elseif k == 0x04; delete!(store_cr_f32, ws_ptr)
  elseif k == 0x05; delete!(store_cr_f64, ws_ptr)
  elseif k == 0x06; delete!(store_cr_cf32, ws_ptr)
  elseif k == 0x07; delete!(store_cr_cf64, ws_ptr)
  elseif k == 0x08; delete!(store_symmlq_f32, ws_ptr)
  elseif k == 0x09; delete!(store_symmlq_f64, ws_ptr)
  elseif k == 0x0a; delete!(store_symmlq_cf32, ws_ptr)
  elseif k == 0x0b; delete!(store_symmlq_cf64, ws_ptr)
  elseif k == 0x0c; delete!(store_minres_f32, ws_ptr)
  elseif k == 0x0d; delete!(store_minres_f64, ws_ptr)
  elseif k == 0x0e; delete!(store_minres_cf32, ws_ptr)
  elseif k == 0x0f; delete!(store_minres_cf64, ws_ptr)
  elseif k == 0x10; delete!(store_minres_qlp_f32, ws_ptr)
  elseif k == 0x11; delete!(store_minres_qlp_f64, ws_ptr)
  elseif k == 0x12; delete!(store_minres_qlp_cf32, ws_ptr)
  elseif k == 0x13; delete!(store_minres_qlp_cf64, ws_ptr)
  elseif k == 0x14; delete!(store_diom_f32, ws_ptr)
  elseif k == 0x15; delete!(store_diom_f64, ws_ptr)
  elseif k == 0x16; delete!(store_diom_cf32, ws_ptr)
  elseif k == 0x17; delete!(store_diom_cf64, ws_ptr)
  elseif k == 0x18; delete!(store_dqgmres_f32, ws_ptr)
  elseif k == 0x19; delete!(store_dqgmres_f64, ws_ptr)
  elseif k == 0x1a; delete!(store_dqgmres_cf32, ws_ptr)
  elseif k == 0x1b; delete!(store_dqgmres_cf64, ws_ptr)
  elseif k == 0x1c; delete!(store_fom_f32, ws_ptr)
  elseif k == 0x1d; delete!(store_fom_f64, ws_ptr)
  elseif k == 0x1e; delete!(store_fom_cf32, ws_ptr)
  elseif k == 0x1f; delete!(store_fom_cf64, ws_ptr)
  elseif k == 0x20; delete!(store_gmres_f32, ws_ptr)
  elseif k == 0x21; delete!(store_gmres_f64, ws_ptr)
  elseif k == 0x22; delete!(store_gmres_cf32, ws_ptr)
  elseif k == 0x23; delete!(store_gmres_cf64, ws_ptr)
  elseif k == 0x24; delete!(store_fgmres_f32, ws_ptr)
  elseif k == 0x25; delete!(store_fgmres_f64, ws_ptr)
  elseif k == 0x26; delete!(store_fgmres_cf32, ws_ptr)
  elseif k == 0x27; delete!(store_fgmres_cf64, ws_ptr)
  elseif k == 0x28; delete!(store_bicgstab_f32, ws_ptr)
  elseif k == 0x29; delete!(store_bicgstab_f64, ws_ptr)
  elseif k == 0x2a; delete!(store_bicgstab_cf32, ws_ptr)
  elseif k == 0x2b; delete!(store_bicgstab_cf64, ws_ptr)
  elseif k == 0x2c; delete!(store_cgs_f32, ws_ptr)
  elseif k == 0x2d; delete!(store_cgs_f64, ws_ptr)
  elseif k == 0x2e; delete!(store_cgs_cf32, ws_ptr)
  elseif k == 0x2f; delete!(store_cgs_cf64, ws_ptr)
  elseif k == 0x30; delete!(store_bilq_f32, ws_ptr)
  elseif k == 0x31; delete!(store_bilq_f64, ws_ptr)
  elseif k == 0x32; delete!(store_bilq_cf32, ws_ptr)
  elseif k == 0x33; delete!(store_bilq_cf64, ws_ptr)
  elseif k == 0x34; delete!(store_qmr_f32, ws_ptr)
  elseif k == 0x35; delete!(store_qmr_f64, ws_ptr)
  elseif k == 0x36; delete!(store_qmr_cf32, ws_ptr)
  elseif k == 0x37; delete!(store_qmr_cf64, ws_ptr)
  elseif k == 0x38; delete!(store_usymlq_f32, ws_ptr)
  elseif k == 0x39; delete!(store_usymlq_f64, ws_ptr)
  elseif k == 0x3a; delete!(store_usymlq_cf32, ws_ptr)
  elseif k == 0x3b; delete!(store_usymlq_cf64, ws_ptr)
  elseif k == 0x3c; delete!(store_usymqr_f32, ws_ptr)
  elseif k == 0x3d; delete!(store_usymqr_f64, ws_ptr)
  elseif k == 0x3e; delete!(store_usymqr_cf32, ws_ptr)
  elseif k == 0x3f; delete!(store_usymqr_cf64, ws_ptr)
  elseif k == 0x40; delete!(store_tricg_f32, ws_ptr)
  elseif k == 0x41; delete!(store_tricg_f64, ws_ptr)
  elseif k == 0x42; delete!(store_tricg_cf32, ws_ptr)
  elseif k == 0x43; delete!(store_tricg_cf64, ws_ptr)
  elseif k == 0x44; delete!(store_trimr_f32, ws_ptr)
  elseif k == 0x45; delete!(store_trimr_f64, ws_ptr)
  elseif k == 0x46; delete!(store_trimr_cf32, ws_ptr)
  elseif k == 0x47; delete!(store_trimr_cf64, ws_ptr)
  elseif k == 0x48; delete!(store_trilqr_f32, ws_ptr)
  elseif k == 0x49; delete!(store_trilqr_f64, ws_ptr)
  elseif k == 0x4a; delete!(store_trilqr_cf32, ws_ptr)
  elseif k == 0x4b; delete!(store_trilqr_cf64, ws_ptr)
  elseif k == 0x4c; delete!(store_bilqr_f32, ws_ptr)
  elseif k == 0x4d; delete!(store_bilqr_f64, ws_ptr)
  elseif k == 0x4e; delete!(store_bilqr_cf32, ws_ptr)
  elseif k == 0x4f; delete!(store_bilqr_cf64, ws_ptr)
  elseif k == 0x50; delete!(store_lslq_f32, ws_ptr)
  elseif k == 0x51; delete!(store_lslq_f64, ws_ptr)
  elseif k == 0x52; delete!(store_lslq_cf32, ws_ptr)
  elseif k == 0x53; delete!(store_lslq_cf64, ws_ptr)
  elseif k == 0x54; delete!(store_lsqr_f32, ws_ptr)
  elseif k == 0x55; delete!(store_lsqr_f64, ws_ptr)
  elseif k == 0x56; delete!(store_lsqr_cf32, ws_ptr)
  elseif k == 0x57; delete!(store_lsqr_cf64, ws_ptr)
  elseif k == 0x58; delete!(store_lsmr_f32, ws_ptr)
  elseif k == 0x59; delete!(store_lsmr_f64, ws_ptr)
  elseif k == 0x5a; delete!(store_lsmr_cf32, ws_ptr)
  elseif k == 0x5b; delete!(store_lsmr_cf64, ws_ptr)
  elseif k == 0x5c; delete!(store_usymlqr_f32, ws_ptr)
  elseif k == 0x5d; delete!(store_usymlqr_f64, ws_ptr)
  elseif k == 0x5e; delete!(store_usymlqr_cf32, ws_ptr)
  elseif k == 0x5f; delete!(store_usymlqr_cf64, ws_ptr)
  elseif k == 0x60; delete!(store_cgls_f32, ws_ptr)
  elseif k == 0x61; delete!(store_cgls_f64, ws_ptr)
  elseif k == 0x62; delete!(store_cgls_cf32, ws_ptr)
  elseif k == 0x63; delete!(store_cgls_cf64, ws_ptr)
  elseif k == 0x64; delete!(store_crls_f32, ws_ptr)
  elseif k == 0x65; delete!(store_crls_f64, ws_ptr)
  elseif k == 0x66; delete!(store_crls_cf32, ws_ptr)
  elseif k == 0x67; delete!(store_crls_cf64, ws_ptr)
  elseif k == 0x68; delete!(store_cgne_f32, ws_ptr)
  elseif k == 0x69; delete!(store_cgne_f64, ws_ptr)
  elseif k == 0x6a; delete!(store_cgne_cf32, ws_ptr)
  elseif k == 0x6b; delete!(store_cgne_cf64, ws_ptr)
  elseif k == 0x6c; delete!(store_crmr_f32, ws_ptr)
  elseif k == 0x6d; delete!(store_crmr_f64, ws_ptr)
  elseif k == 0x6e; delete!(store_crmr_cf32, ws_ptr)
  elseif k == 0x6f; delete!(store_crmr_cf64, ws_ptr)
  elseif k == 0x70; delete!(store_craig_f32, ws_ptr)
  elseif k == 0x71; delete!(store_craig_f64, ws_ptr)
  elseif k == 0x72; delete!(store_craig_cf32, ws_ptr)
  elseif k == 0x73; delete!(store_craig_cf64, ws_ptr)
  elseif k == 0x74; delete!(store_craigmr_f32, ws_ptr)
  elseif k == 0x75; delete!(store_craigmr_f64, ws_ptr)
  elseif k == 0x76; delete!(store_craigmr_cf32, ws_ptr)
  elseif k == 0x77; delete!(store_craigmr_cf64, ws_ptr)
  elseif k == 0x78; delete!(store_lnlq_f32, ws_ptr)
  elseif k == 0x79; delete!(store_lnlq_f64, ws_ptr)
  elseif k == 0x7a; delete!(store_lnlq_cf32, ws_ptr)
  elseif k == 0x7b; delete!(store_lnlq_cf64, ws_ptr)
  elseif k == 0x7c; delete!(store_gpmr_f32, ws_ptr)
  elseif k == 0x7d; delete!(store_gpmr_f64, ws_ptr)
  elseif k == 0x7e; delete!(store_gpmr_cf32, ws_ptr)
  elseif k == 0x7f; delete!(store_gpmr_cf64, ws_ptr)
  elseif k == 0x80; delete!(store_car_f32, ws_ptr)
  elseif k == 0x81; delete!(store_car_f64, ws_ptr)
  elseif k == 0x82; delete!(store_car_cf32, ws_ptr)
  elseif k == 0x83; delete!(store_car_cf64, ws_ptr)
  elseif k == 0x84; delete!(store_minares_f32, ws_ptr)
  elseif k == 0x85; delete!(store_minares_f64, ws_ptr)
  elseif k == 0x86; delete!(store_minares_cf32, ws_ptr)
  elseif k == 0x87; delete!(store_minares_cf64, ws_ptr)
  end
  Cint(0)
end

function _do_create!(solver_int :: Cint, m :: Cint, n :: Cint,
                     dtype_int :: Cint, wopts :: KrylovWorkspaceOptionsC,
                     ws_out :: Ptr{Ptr{Cvoid}})
  mem = wopts.memory == 0 ? 20 : Int(wopts.memory)
  win = wopts.window == 0 ? 5 : Int(wopts.window)
  if solver_int == Cint(0) && dtype_int == Cint(0)
    ws = Krylov.CgWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_cg_f32[r] = ws; ws_key_store[r] = 0x00
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(1)
    ws = Krylov.CgWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_cg_f64[r] = ws; ws_key_store[r] = 0x01
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(2)
    ws = Krylov.CgWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_cg_cf32[r] = ws; ws_key_store[r] = 0x02
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(3)
    ws = Krylov.CgWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_cg_cf64[r] = ws; ws_key_store[r] = 0x03
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(0)
    ws = Krylov.CrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_cr_f32[r] = ws; ws_key_store[r] = 0x04
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(1)
    ws = Krylov.CrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_cr_f64[r] = ws; ws_key_store[r] = 0x05
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(2)
    ws = Krylov.CrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_cr_cf32[r] = ws; ws_key_store[r] = 0x06
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(3)
    ws = Krylov.CrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_cr_cf64[r] = ws; ws_key_store[r] = 0x07
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(2) && dtype_int == Cint(0)
    ws = Krylov.SymmlqWorkspace(Int(m), Int(n), Vector{Float32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_symmlq_f32[r] = ws; ws_key_store[r] = 0x08
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(2) && dtype_int == Cint(1)
    ws = Krylov.SymmlqWorkspace(Int(m), Int(n), Vector{Float64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_symmlq_f64[r] = ws; ws_key_store[r] = 0x09
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(2) && dtype_int == Cint(2)
    ws = Krylov.SymmlqWorkspace(Int(m), Int(n), Vector{ComplexF32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_symmlq_cf32[r] = ws; ws_key_store[r] = 0x0a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(2) && dtype_int == Cint(3)
    ws = Krylov.SymmlqWorkspace(Int(m), Int(n), Vector{ComplexF64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_symmlq_cf64[r] = ws; ws_key_store[r] = 0x0b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(3) && dtype_int == Cint(0)
    ws = Krylov.MinresWorkspace(Int(m), Int(n), Vector{Float32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_minres_f32[r] = ws; ws_key_store[r] = 0x0c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(3) && dtype_int == Cint(1)
    ws = Krylov.MinresWorkspace(Int(m), Int(n), Vector{Float64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_minres_f64[r] = ws; ws_key_store[r] = 0x0d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(3) && dtype_int == Cint(2)
    ws = Krylov.MinresWorkspace(Int(m), Int(n), Vector{ComplexF32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_minres_cf32[r] = ws; ws_key_store[r] = 0x0e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(3) && dtype_int == Cint(3)
    ws = Krylov.MinresWorkspace(Int(m), Int(n), Vector{ComplexF64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_minres_cf64[r] = ws; ws_key_store[r] = 0x0f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(4) && dtype_int == Cint(0)
    ws = Krylov.MinresQlpWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_minres_qlp_f32[r] = ws; ws_key_store[r] = 0x10
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(4) && dtype_int == Cint(1)
    ws = Krylov.MinresQlpWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_minres_qlp_f64[r] = ws; ws_key_store[r] = 0x11
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(4) && dtype_int == Cint(2)
    ws = Krylov.MinresQlpWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_minres_qlp_cf32[r] = ws; ws_key_store[r] = 0x12
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(4) && dtype_int == Cint(3)
    ws = Krylov.MinresQlpWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_minres_qlp_cf64[r] = ws; ws_key_store[r] = 0x13
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(5) && dtype_int == Cint(0)
    ws = Krylov.DiomWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_diom_f32[r] = ws; ws_key_store[r] = 0x14
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(5) && dtype_int == Cint(1)
    ws = Krylov.DiomWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_diom_f64[r] = ws; ws_key_store[r] = 0x15
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(5) && dtype_int == Cint(2)
    ws = Krylov.DiomWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_diom_cf32[r] = ws; ws_key_store[r] = 0x16
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(5) && dtype_int == Cint(3)
    ws = Krylov.DiomWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_diom_cf64[r] = ws; ws_key_store[r] = 0x17
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(6) && dtype_int == Cint(0)
    ws = Krylov.DqgmresWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_dqgmres_f32[r] = ws; ws_key_store[r] = 0x18
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(6) && dtype_int == Cint(1)
    ws = Krylov.DqgmresWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_dqgmres_f64[r] = ws; ws_key_store[r] = 0x19
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(6) && dtype_int == Cint(2)
    ws = Krylov.DqgmresWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_dqgmres_cf32[r] = ws; ws_key_store[r] = 0x1a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(6) && dtype_int == Cint(3)
    ws = Krylov.DqgmresWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_dqgmres_cf64[r] = ws; ws_key_store[r] = 0x1b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(7) && dtype_int == Cint(0)
    ws = Krylov.FomWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fom_f32[r] = ws; ws_key_store[r] = 0x1c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(7) && dtype_int == Cint(1)
    ws = Krylov.FomWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fom_f64[r] = ws; ws_key_store[r] = 0x1d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(7) && dtype_int == Cint(2)
    ws = Krylov.FomWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fom_cf32[r] = ws; ws_key_store[r] = 0x1e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(7) && dtype_int == Cint(3)
    ws = Krylov.FomWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fom_cf64[r] = ws; ws_key_store[r] = 0x1f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(8) && dtype_int == Cint(0)
    ws = Krylov.GmresWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gmres_f32[r] = ws; ws_key_store[r] = 0x20
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(8) && dtype_int == Cint(1)
    ws = Krylov.GmresWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gmres_f64[r] = ws; ws_key_store[r] = 0x21
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(8) && dtype_int == Cint(2)
    ws = Krylov.GmresWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gmres_cf32[r] = ws; ws_key_store[r] = 0x22
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(8) && dtype_int == Cint(3)
    ws = Krylov.GmresWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gmres_cf64[r] = ws; ws_key_store[r] = 0x23
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(9) && dtype_int == Cint(0)
    ws = Krylov.FgmresWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fgmres_f32[r] = ws; ws_key_store[r] = 0x24
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(9) && dtype_int == Cint(1)
    ws = Krylov.FgmresWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fgmres_f64[r] = ws; ws_key_store[r] = 0x25
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(9) && dtype_int == Cint(2)
    ws = Krylov.FgmresWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fgmres_cf32[r] = ws; ws_key_store[r] = 0x26
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(9) && dtype_int == Cint(3)
    ws = Krylov.FgmresWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_fgmres_cf64[r] = ws; ws_key_store[r] = 0x27
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(10) && dtype_int == Cint(0)
    ws = Krylov.BicgstabWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_bicgstab_f32[r] = ws; ws_key_store[r] = 0x28
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(10) && dtype_int == Cint(1)
    ws = Krylov.BicgstabWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_bicgstab_f64[r] = ws; ws_key_store[r] = 0x29
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(10) && dtype_int == Cint(2)
    ws = Krylov.BicgstabWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_bicgstab_cf32[r] = ws; ws_key_store[r] = 0x2a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(10) && dtype_int == Cint(3)
    ws = Krylov.BicgstabWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_bicgstab_cf64[r] = ws; ws_key_store[r] = 0x2b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(11) && dtype_int == Cint(0)
    ws = Krylov.CgsWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_cgs_f32[r] = ws; ws_key_store[r] = 0x2c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(11) && dtype_int == Cint(1)
    ws = Krylov.CgsWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_cgs_f64[r] = ws; ws_key_store[r] = 0x2d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(11) && dtype_int == Cint(2)
    ws = Krylov.CgsWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_cgs_cf32[r] = ws; ws_key_store[r] = 0x2e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(11) && dtype_int == Cint(3)
    ws = Krylov.CgsWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_cgs_cf64[r] = ws; ws_key_store[r] = 0x2f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(12) && dtype_int == Cint(0)
    ws = Krylov.BilqWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_bilq_f32[r] = ws; ws_key_store[r] = 0x30
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(12) && dtype_int == Cint(1)
    ws = Krylov.BilqWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_bilq_f64[r] = ws; ws_key_store[r] = 0x31
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(12) && dtype_int == Cint(2)
    ws = Krylov.BilqWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_bilq_cf32[r] = ws; ws_key_store[r] = 0x32
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(12) && dtype_int == Cint(3)
    ws = Krylov.BilqWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_bilq_cf64[r] = ws; ws_key_store[r] = 0x33
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(13) && dtype_int == Cint(0)
    ws = Krylov.QmrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_qmr_f32[r] = ws; ws_key_store[r] = 0x34
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(13) && dtype_int == Cint(1)
    ws = Krylov.QmrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_qmr_f64[r] = ws; ws_key_store[r] = 0x35
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(13) && dtype_int == Cint(2)
    ws = Krylov.QmrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_qmr_cf32[r] = ws; ws_key_store[r] = 0x36
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(13) && dtype_int == Cint(3)
    ws = Krylov.QmrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_qmr_cf64[r] = ws; ws_key_store[r] = 0x37
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(14) && dtype_int == Cint(0)
    ws = Krylov.UsymlqWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_usymlq_f32[r] = ws; ws_key_store[r] = 0x38
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(14) && dtype_int == Cint(1)
    ws = Krylov.UsymlqWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_usymlq_f64[r] = ws; ws_key_store[r] = 0x39
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(14) && dtype_int == Cint(2)
    ws = Krylov.UsymlqWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_usymlq_cf32[r] = ws; ws_key_store[r] = 0x3a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(14) && dtype_int == Cint(3)
    ws = Krylov.UsymlqWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_usymlq_cf64[r] = ws; ws_key_store[r] = 0x3b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(15) && dtype_int == Cint(0)
    ws = Krylov.UsymqrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_usymqr_f32[r] = ws; ws_key_store[r] = 0x3c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(15) && dtype_int == Cint(1)
    ws = Krylov.UsymqrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_usymqr_f64[r] = ws; ws_key_store[r] = 0x3d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(15) && dtype_int == Cint(2)
    ws = Krylov.UsymqrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_usymqr_cf32[r] = ws; ws_key_store[r] = 0x3e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(15) && dtype_int == Cint(3)
    ws = Krylov.UsymqrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_usymqr_cf64[r] = ws; ws_key_store[r] = 0x3f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(16) && dtype_int == Cint(0)
    ws = Krylov.TricgWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_tricg_f32[r] = ws; ws_key_store[r] = 0x40
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(16) && dtype_int == Cint(1)
    ws = Krylov.TricgWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_tricg_f64[r] = ws; ws_key_store[r] = 0x41
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(16) && dtype_int == Cint(2)
    ws = Krylov.TricgWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_tricg_cf32[r] = ws; ws_key_store[r] = 0x42
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(16) && dtype_int == Cint(3)
    ws = Krylov.TricgWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_tricg_cf64[r] = ws; ws_key_store[r] = 0x43
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(17) && dtype_int == Cint(0)
    ws = Krylov.TrimrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_trimr_f32[r] = ws; ws_key_store[r] = 0x44
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(17) && dtype_int == Cint(1)
    ws = Krylov.TrimrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_trimr_f64[r] = ws; ws_key_store[r] = 0x45
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(17) && dtype_int == Cint(2)
    ws = Krylov.TrimrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_trimr_cf32[r] = ws; ws_key_store[r] = 0x46
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(17) && dtype_int == Cint(3)
    ws = Krylov.TrimrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_trimr_cf64[r] = ws; ws_key_store[r] = 0x47
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(18) && dtype_int == Cint(0)
    ws = Krylov.TrilqrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_trilqr_f32[r] = ws; ws_key_store[r] = 0x48
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(18) && dtype_int == Cint(1)
    ws = Krylov.TrilqrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_trilqr_f64[r] = ws; ws_key_store[r] = 0x49
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(18) && dtype_int == Cint(2)
    ws = Krylov.TrilqrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_trilqr_cf32[r] = ws; ws_key_store[r] = 0x4a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(18) && dtype_int == Cint(3)
    ws = Krylov.TrilqrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_trilqr_cf64[r] = ws; ws_key_store[r] = 0x4b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(19) && dtype_int == Cint(0)
    ws = Krylov.BilqrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_bilqr_f32[r] = ws; ws_key_store[r] = 0x4c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(19) && dtype_int == Cint(1)
    ws = Krylov.BilqrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_bilqr_f64[r] = ws; ws_key_store[r] = 0x4d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(19) && dtype_int == Cint(2)
    ws = Krylov.BilqrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_bilqr_cf32[r] = ws; ws_key_store[r] = 0x4e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(19) && dtype_int == Cint(3)
    ws = Krylov.BilqrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_bilqr_cf64[r] = ws; ws_key_store[r] = 0x4f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(20) && dtype_int == Cint(0)
    ws = Krylov.LslqWorkspace(Int(m), Int(n), Vector{Float32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lslq_f32[r] = ws; ws_key_store[r] = 0x50
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(20) && dtype_int == Cint(1)
    ws = Krylov.LslqWorkspace(Int(m), Int(n), Vector{Float64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lslq_f64[r] = ws; ws_key_store[r] = 0x51
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(20) && dtype_int == Cint(2)
    ws = Krylov.LslqWorkspace(Int(m), Int(n), Vector{ComplexF32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lslq_cf32[r] = ws; ws_key_store[r] = 0x52
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(20) && dtype_int == Cint(3)
    ws = Krylov.LslqWorkspace(Int(m), Int(n), Vector{ComplexF64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lslq_cf64[r] = ws; ws_key_store[r] = 0x53
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(21) && dtype_int == Cint(0)
    ws = Krylov.LsqrWorkspace(Int(m), Int(n), Vector{Float32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsqr_f32[r] = ws; ws_key_store[r] = 0x54
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(21) && dtype_int == Cint(1)
    ws = Krylov.LsqrWorkspace(Int(m), Int(n), Vector{Float64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsqr_f64[r] = ws; ws_key_store[r] = 0x55
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(21) && dtype_int == Cint(2)
    ws = Krylov.LsqrWorkspace(Int(m), Int(n), Vector{ComplexF32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsqr_cf32[r] = ws; ws_key_store[r] = 0x56
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(21) && dtype_int == Cint(3)
    ws = Krylov.LsqrWorkspace(Int(m), Int(n), Vector{ComplexF64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsqr_cf64[r] = ws; ws_key_store[r] = 0x57
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(22) && dtype_int == Cint(0)
    ws = Krylov.LsmrWorkspace(Int(m), Int(n), Vector{Float32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsmr_f32[r] = ws; ws_key_store[r] = 0x58
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(22) && dtype_int == Cint(1)
    ws = Krylov.LsmrWorkspace(Int(m), Int(n), Vector{Float64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsmr_f64[r] = ws; ws_key_store[r] = 0x59
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(22) && dtype_int == Cint(2)
    ws = Krylov.LsmrWorkspace(Int(m), Int(n), Vector{ComplexF32}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsmr_cf32[r] = ws; ws_key_store[r] = 0x5a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(22) && dtype_int == Cint(3)
    ws = Krylov.LsmrWorkspace(Int(m), Int(n), Vector{ComplexF64}; window = win)
    r  = Base.pointer_from_objref(ws)
    store_lsmr_cf64[r] = ws; ws_key_store[r] = 0x5b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(23) && dtype_int == Cint(0)
    ws = Krylov.UsymlqrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_usymlqr_f32[r] = ws; ws_key_store[r] = 0x5c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(23) && dtype_int == Cint(1)
    ws = Krylov.UsymlqrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_usymlqr_f64[r] = ws; ws_key_store[r] = 0x5d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(23) && dtype_int == Cint(2)
    ws = Krylov.UsymlqrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_usymlqr_cf32[r] = ws; ws_key_store[r] = 0x5e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(23) && dtype_int == Cint(3)
    ws = Krylov.UsymlqrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_usymlqr_cf64[r] = ws; ws_key_store[r] = 0x5f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(24) && dtype_int == Cint(0)
    ws = Krylov.CglsWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_cgls_f32[r] = ws; ws_key_store[r] = 0x60
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(24) && dtype_int == Cint(1)
    ws = Krylov.CglsWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_cgls_f64[r] = ws; ws_key_store[r] = 0x61
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(24) && dtype_int == Cint(2)
    ws = Krylov.CglsWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_cgls_cf32[r] = ws; ws_key_store[r] = 0x62
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(24) && dtype_int == Cint(3)
    ws = Krylov.CglsWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_cgls_cf64[r] = ws; ws_key_store[r] = 0x63
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(25) && dtype_int == Cint(0)
    ws = Krylov.CrlsWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_crls_f32[r] = ws; ws_key_store[r] = 0x64
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(25) && dtype_int == Cint(1)
    ws = Krylov.CrlsWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_crls_f64[r] = ws; ws_key_store[r] = 0x65
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(25) && dtype_int == Cint(2)
    ws = Krylov.CrlsWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_crls_cf32[r] = ws; ws_key_store[r] = 0x66
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(25) && dtype_int == Cint(3)
    ws = Krylov.CrlsWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_crls_cf64[r] = ws; ws_key_store[r] = 0x67
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(26) && dtype_int == Cint(0)
    ws = Krylov.CgneWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_cgne_f32[r] = ws; ws_key_store[r] = 0x68
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(26) && dtype_int == Cint(1)
    ws = Krylov.CgneWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_cgne_f64[r] = ws; ws_key_store[r] = 0x69
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(26) && dtype_int == Cint(2)
    ws = Krylov.CgneWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_cgne_cf32[r] = ws; ws_key_store[r] = 0x6a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(26) && dtype_int == Cint(3)
    ws = Krylov.CgneWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_cgne_cf64[r] = ws; ws_key_store[r] = 0x6b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(27) && dtype_int == Cint(0)
    ws = Krylov.CrmrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_crmr_f32[r] = ws; ws_key_store[r] = 0x6c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(27) && dtype_int == Cint(1)
    ws = Krylov.CrmrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_crmr_f64[r] = ws; ws_key_store[r] = 0x6d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(27) && dtype_int == Cint(2)
    ws = Krylov.CrmrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_crmr_cf32[r] = ws; ws_key_store[r] = 0x6e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(27) && dtype_int == Cint(3)
    ws = Krylov.CrmrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_crmr_cf64[r] = ws; ws_key_store[r] = 0x6f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(28) && dtype_int == Cint(0)
    ws = Krylov.CraigWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_craig_f32[r] = ws; ws_key_store[r] = 0x70
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(28) && dtype_int == Cint(1)
    ws = Krylov.CraigWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_craig_f64[r] = ws; ws_key_store[r] = 0x71
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(28) && dtype_int == Cint(2)
    ws = Krylov.CraigWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_craig_cf32[r] = ws; ws_key_store[r] = 0x72
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(28) && dtype_int == Cint(3)
    ws = Krylov.CraigWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_craig_cf64[r] = ws; ws_key_store[r] = 0x73
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(29) && dtype_int == Cint(0)
    ws = Krylov.CraigmrWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_craigmr_f32[r] = ws; ws_key_store[r] = 0x74
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(29) && dtype_int == Cint(1)
    ws = Krylov.CraigmrWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_craigmr_f64[r] = ws; ws_key_store[r] = 0x75
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(29) && dtype_int == Cint(2)
    ws = Krylov.CraigmrWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_craigmr_cf32[r] = ws; ws_key_store[r] = 0x76
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(29) && dtype_int == Cint(3)
    ws = Krylov.CraigmrWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_craigmr_cf64[r] = ws; ws_key_store[r] = 0x77
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(30) && dtype_int == Cint(0)
    ws = Krylov.LnlqWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_lnlq_f32[r] = ws; ws_key_store[r] = 0x78
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(30) && dtype_int == Cint(1)
    ws = Krylov.LnlqWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_lnlq_f64[r] = ws; ws_key_store[r] = 0x79
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(30) && dtype_int == Cint(2)
    ws = Krylov.LnlqWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_lnlq_cf32[r] = ws; ws_key_store[r] = 0x7a
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(30) && dtype_int == Cint(3)
    ws = Krylov.LnlqWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_lnlq_cf64[r] = ws; ws_key_store[r] = 0x7b
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(31) && dtype_int == Cint(0)
    ws = Krylov.GpmrWorkspace(Int(m), Int(n), Vector{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gpmr_f32[r] = ws; ws_key_store[r] = 0x7c
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(31) && dtype_int == Cint(1)
    ws = Krylov.GpmrWorkspace(Int(m), Int(n), Vector{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gpmr_f64[r] = ws; ws_key_store[r] = 0x7d
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(31) && dtype_int == Cint(2)
    ws = Krylov.GpmrWorkspace(Int(m), Int(n), Vector{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gpmr_cf32[r] = ws; ws_key_store[r] = 0x7e
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(31) && dtype_int == Cint(3)
    ws = Krylov.GpmrWorkspace(Int(m), Int(n), Vector{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_gpmr_cf64[r] = ws; ws_key_store[r] = 0x7f
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(32) && dtype_int == Cint(0)
    ws = Krylov.CarWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_car_f32[r] = ws; ws_key_store[r] = 0x80
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(32) && dtype_int == Cint(1)
    ws = Krylov.CarWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_car_f64[r] = ws; ws_key_store[r] = 0x81
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(32) && dtype_int == Cint(2)
    ws = Krylov.CarWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_car_cf32[r] = ws; ws_key_store[r] = 0x82
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(32) && dtype_int == Cint(3)
    ws = Krylov.CarWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_car_cf64[r] = ws; ws_key_store[r] = 0x83
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(33) && dtype_int == Cint(0)
    ws = Krylov.MinaresWorkspace(Int(m), Int(n), Vector{Float32})
    r  = Base.pointer_from_objref(ws)
    store_minares_f32[r] = ws; ws_key_store[r] = 0x84
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(33) && dtype_int == Cint(1)
    ws = Krylov.MinaresWorkspace(Int(m), Int(n), Vector{Float64})
    r  = Base.pointer_from_objref(ws)
    store_minares_f64[r] = ws; ws_key_store[r] = 0x85
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(33) && dtype_int == Cint(2)
    ws = Krylov.MinaresWorkspace(Int(m), Int(n), Vector{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_minares_cf32[r] = ws; ws_key_store[r] = 0x86
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(33) && dtype_int == Cint(3)
    ws = Krylov.MinaresWorkspace(Int(m), Int(n), Vector{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_minares_cf64[r] = ws; ws_key_store[r] = 0x87
    unsafe_store!(ws_out, r)
  else
    return Cint(-2)  # unknown (solver, dtype) combination
  end
  Cint(0)
end

# ---------------------------------------------------------------------------
# Block Krylov stores — 2 solvers × 4 precisions = 8 combos.
# SV = Vector{FC}, SM = Matrix{FC}.  Keyed separately from the scalar stores.
# ---------------------------------------------------------------------------

const store_block_gmres_f32 = Dict{Ptr{Cvoid}, Krylov.BlockGmresWorkspace{Float32, Float32, Vector{Float32}, Matrix{Float32}}}()
const store_block_gmres_f64 = Dict{Ptr{Cvoid}, Krylov.BlockGmresWorkspace{Float64, Float64, Vector{Float64}, Matrix{Float64}}}()
const store_block_gmres_cf32 = Dict{Ptr{Cvoid}, Krylov.BlockGmresWorkspace{Float32, ComplexF32, Vector{ComplexF32}, Matrix{ComplexF32}}}()
const store_block_gmres_cf64 = Dict{Ptr{Cvoid}, Krylov.BlockGmresWorkspace{Float64, ComplexF64, Vector{ComplexF64}, Matrix{ComplexF64}}}()

const store_block_minres_f32 = Dict{Ptr{Cvoid}, Krylov.BlockMinresWorkspace{Float32, Float32, Vector{Float32}, Matrix{Float32}}}()
const store_block_minres_f64 = Dict{Ptr{Cvoid}, Krylov.BlockMinresWorkspace{Float64, Float64, Vector{Float64}, Matrix{Float64}}}()
const store_block_minres_cf32 = Dict{Ptr{Cvoid}, Krylov.BlockMinresWorkspace{Float32, ComplexF32, Vector{ComplexF32}, Matrix{ComplexF32}}}()
const store_block_minres_cf64 = Dict{Ptr{Cvoid}, Krylov.BlockMinresWorkspace{Float64, ComplexF64, Vector{ComplexF64}, Matrix{ComplexF64}}}()

const block_ws_key_store = Dict{Ptr{Cvoid}, UInt8}()

# ---------------------------------------------------------------------------
# Generic typed helpers for block workspaces.
# ---------------------------------------------------------------------------
function _typed_block_niter(ws)
  Cint(ws.stats.niter)
end

function _typed_block_is_solved(ws)
  ws.stats.solved ? Cint(1) : Cint(0)
end

function _typed_block_elapsed_time(ws)
  Cdouble(ws.stats.timer)
end

function _typed_block_get_X!(ws::Krylov.BlockKrylovWorkspace{T, FC, SV, SM}, X_ptr, n, p) where {T, FC, SV, SM}
  copyto!(unsafe_wrap(Matrix{FC}, Ptr{FC}(X_ptr), (Int(n), Int(p))), ws.X)
  Cint(0)
end

function _typed_block_warm_start!(ws::Krylov.BlockKrylovWorkspace{T, FC, SV, SM}, X0_ptr, n, p) where {T, FC, SV, SM}
  X0 = unsafe_wrap(Matrix{FC}, Ptr{FC}(X0_ptr), (Int(n), Int(p)))
  if size(ws.ΔX) != (ws.n, ws.p)
    ws.ΔX = SM(undef, ws.n, ws.p)
  end
  copyto!(ws.ΔX, X0)
  ws.warm_start = true
  Cint(0)
end

# Block solve — uses the GENERIC krylov_solve! (dispatch on the workspace type
# picks block_gmres! / block_minres!).  Going through the generic interface is
# what makes the call trim-safe: it forwards every keyword with its default
# (restart=false, ldiv=false, …) as a literal, so allocate_if(restart, …) is
# constant-folded away — a direct block_gmres! call is NOT trim-safe.
# Supports an optional left preconditioner M (applied as Y = M⁻¹X).
# fptr_N is part of the shared signature but ignored: block_minres takes M only.
function _typed_block_solve!(ws::Krylov.BlockKrylovWorkspace{T, FC, SV, SM}, fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts) where {T, FC, SV, SM}
  A  = CBlockOperator{FC}(ws.m, ws.n, fptr_A, userdata)
  B  = unsafe_wrap(Matrix{FC}, Ptr{FC}(B_ptr), (ws.m, ws.p))
  kw = _opts_kw(opts, T)
  if fptr_M != C_NULL
    M = CBlockOperator{FC}(ws.n, ws.n, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, B; M=M, kw...)
  else
    Krylov.krylov_solve!(ws, A, B; kw...)
  end
  Cint(0)
end

# block_gmres accepts BOTH a left (M) and right (N) preconditioner.  As for the
# single-vector _typed_solve_mn!, the four combinations are spelled out to keep
# each krylov_solve! call site concretely typed for --trim=safe.
function _typed_block_solve_mn!(ws::Krylov.BlockKrylovWorkspace{T, FC, SV, SM}, fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts) where {T, FC, SV, SM}
  A  = CBlockOperator{FC}(ws.m, ws.n, fptr_A, userdata)
  B  = unsafe_wrap(Matrix{FC}, Ptr{FC}(B_ptr), (ws.m, ws.p))
  kw = _opts_kw(opts, T)
  rs = opts.restart != 0; ro = opts.reorthogonalization != 0
  if fptr_M != C_NULL && fptr_N != C_NULL
    M = CBlockOperator{FC}(ws.m, ws.m, fptr_M, userdata)
    N = CBlockOperator{FC}(ws.n, ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, B; M=M, N=N, restart=rs, reorthogonalization=ro, kw...)
  elseif fptr_M != C_NULL
    M = CBlockOperator{FC}(ws.m, ws.m, fptr_M, userdata)
    Krylov.krylov_solve!(ws, A, B; M=M, restart=rs, reorthogonalization=ro, kw...)
  elseif fptr_N != C_NULL
    N = CBlockOperator{FC}(ws.n, ws.n, fptr_N, userdata)
    Krylov.krylov_solve!(ws, A, B; N=N, restart=rs, reorthogonalization=ro, kw...)
  else
    Krylov.krylov_solve!(ws, A, B; restart=rs, reorthogonalization=ro, kw...)
  end
  Cint(0)
end

function _do_block_niter(ws_ptr :: Ptr{Cvoid})
  haskey(block_ws_key_store, ws_ptr) || return Cint(-1)
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_niter(store_block_gmres_f32[ws_ptr])
  elseif k == 0x01; _typed_block_niter(store_block_gmres_f64[ws_ptr])
  elseif k == 0x02; _typed_block_niter(store_block_gmres_cf32[ws_ptr])
  elseif k == 0x03; _typed_block_niter(store_block_gmres_cf64[ws_ptr])
  elseif k == 0x04; _typed_block_niter(store_block_minres_f32[ws_ptr])
  elseif k == 0x05; _typed_block_niter(store_block_minres_f64[ws_ptr])
  elseif k == 0x06; _typed_block_niter(store_block_minres_cf32[ws_ptr])
  elseif k == 0x07; _typed_block_niter(store_block_minres_cf64[ws_ptr])
  else; Cint(-1); end
end

function _do_block_is_solved(ws_ptr :: Ptr{Cvoid})
  haskey(block_ws_key_store, ws_ptr) || return Cint(-1)
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_is_solved(store_block_gmres_f32[ws_ptr])
  elseif k == 0x01; _typed_block_is_solved(store_block_gmres_f64[ws_ptr])
  elseif k == 0x02; _typed_block_is_solved(store_block_gmres_cf32[ws_ptr])
  elseif k == 0x03; _typed_block_is_solved(store_block_gmres_cf64[ws_ptr])
  elseif k == 0x04; _typed_block_is_solved(store_block_minres_f32[ws_ptr])
  elseif k == 0x05; _typed_block_is_solved(store_block_minres_f64[ws_ptr])
  elseif k == 0x06; _typed_block_is_solved(store_block_minres_cf32[ws_ptr])
  elseif k == 0x07; _typed_block_is_solved(store_block_minres_cf64[ws_ptr])
  else; Cint(-1); end
end

function _do_block_elapsed_time(ws_ptr :: Ptr{Cvoid})
  haskey(block_ws_key_store, ws_ptr) || return Cdouble(-1.0)
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_elapsed_time(store_block_gmres_f32[ws_ptr])
  elseif k == 0x01; _typed_block_elapsed_time(store_block_gmres_f64[ws_ptr])
  elseif k == 0x02; _typed_block_elapsed_time(store_block_gmres_cf32[ws_ptr])
  elseif k == 0x03; _typed_block_elapsed_time(store_block_gmres_cf64[ws_ptr])
  elseif k == 0x04; _typed_block_elapsed_time(store_block_minres_f32[ws_ptr])
  elseif k == 0x05; _typed_block_elapsed_time(store_block_minres_f64[ws_ptr])
  elseif k == 0x06; _typed_block_elapsed_time(store_block_minres_cf32[ws_ptr])
  elseif k == 0x07; _typed_block_elapsed_time(store_block_minres_cf64[ws_ptr])
  else; Cdouble(-1.0); end
end

function _do_block_get_X!(ws_ptr :: Ptr{Cvoid}, X_ptr :: Ptr{Cvoid}, n :: Cint, p :: Cint)
  haskey(block_ws_key_store, ws_ptr) || return Cint(-1)
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_get_X!(store_block_gmres_f32[ws_ptr], X_ptr, n, p)
  elseif k == 0x01; _typed_block_get_X!(store_block_gmres_f64[ws_ptr], X_ptr, n, p)
  elseif k == 0x02; _typed_block_get_X!(store_block_gmres_cf32[ws_ptr], X_ptr, n, p)
  elseif k == 0x03; _typed_block_get_X!(store_block_gmres_cf64[ws_ptr], X_ptr, n, p)
  elseif k == 0x04; _typed_block_get_X!(store_block_minres_f32[ws_ptr], X_ptr, n, p)
  elseif k == 0x05; _typed_block_get_X!(store_block_minres_f64[ws_ptr], X_ptr, n, p)
  elseif k == 0x06; _typed_block_get_X!(store_block_minres_cf32[ws_ptr], X_ptr, n, p)
  elseif k == 0x07; _typed_block_get_X!(store_block_minres_cf64[ws_ptr], X_ptr, n, p)
  else; Cint(-1); end
end

function _do_block_warm_start!(ws_ptr :: Ptr{Cvoid}, X0_ptr :: Ptr{Cvoid}, n :: Cint, p :: Cint)
  haskey(block_ws_key_store, ws_ptr) || return Cint(-1)
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_warm_start!(store_block_gmres_f32[ws_ptr], X0_ptr, n, p)
  elseif k == 0x01; _typed_block_warm_start!(store_block_gmres_f64[ws_ptr], X0_ptr, n, p)
  elseif k == 0x02; _typed_block_warm_start!(store_block_gmres_cf32[ws_ptr], X0_ptr, n, p)
  elseif k == 0x03; _typed_block_warm_start!(store_block_gmres_cf64[ws_ptr], X0_ptr, n, p)
  elseif k == 0x04; _typed_block_warm_start!(store_block_minres_f32[ws_ptr], X0_ptr, n, p)
  elseif k == 0x05; _typed_block_warm_start!(store_block_minres_f64[ws_ptr], X0_ptr, n, p)
  elseif k == 0x06; _typed_block_warm_start!(store_block_minres_cf32[ws_ptr], X0_ptr, n, p)
  elseif k == 0x07; _typed_block_warm_start!(store_block_minres_cf64[ws_ptr], X0_ptr, n, p)
  else; Cint(-1); end
end

function _do_block_solve!(ws_ptr :: Ptr{Cvoid}, fptr_A :: Ptr{Cvoid}, fptr_M :: Ptr{Cvoid}, fptr_N :: Ptr{Cvoid}, B_ptr :: Ptr{Cvoid}, userdata :: Ptr{Cvoid}, opts_ptr :: Ptr{Cvoid})
  haskey(block_ws_key_store, ws_ptr) || return Cint(-1)
  opts = opts_ptr == C_NULL ? KrylovOptionsC(NaN, NaN, Cint(0), Cint(0), 0.0, NaN, NaN, NaN, 0.0, Cint(0), Cint(0), Cint(0)) : unsafe_load(Ptr{KrylovOptionsC}(opts_ptr))
  k = block_ws_key_store[ws_ptr]
  if k == 0x00; _typed_block_solve_mn!(store_block_gmres_f32[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x01; _typed_block_solve_mn!(store_block_gmres_f64[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x02; _typed_block_solve_mn!(store_block_gmres_cf32[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x03; _typed_block_solve_mn!(store_block_gmres_cf64[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x04; _typed_block_solve!(store_block_minres_f32[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x05; _typed_block_solve!(store_block_minres_f64[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x06; _typed_block_solve!(store_block_minres_cf32[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  elseif k == 0x07; _typed_block_solve!(store_block_minres_cf64[ws_ptr], fptr_A, fptr_M, fptr_N, B_ptr, userdata, opts)
  else; Cint(-1); end
end

function _do_block_free!(ws_ptr :: Ptr{Cvoid})
  haskey(block_ws_key_store, ws_ptr) || return Cint(1)
  k = block_ws_key_store[ws_ptr]
  delete!(block_ws_key_store, ws_ptr)
  if k == 0x00; delete!(store_block_gmres_f32, ws_ptr)
  elseif k == 0x01; delete!(store_block_gmres_f64, ws_ptr)
  elseif k == 0x02; delete!(store_block_gmres_cf32, ws_ptr)
  elseif k == 0x03; delete!(store_block_gmres_cf64, ws_ptr)
  elseif k == 0x04; delete!(store_block_minres_f32, ws_ptr)
  elseif k == 0x05; delete!(store_block_minres_f64, ws_ptr)
  elseif k == 0x06; delete!(store_block_minres_cf32, ws_ptr)
  elseif k == 0x07; delete!(store_block_minres_cf64, ws_ptr)
  end
  Cint(0)
end

function _do_block_create!(solver_int :: Cint, m :: Cint, n :: Cint, p :: Cint,
                           dtype_int :: Cint, wopts :: KrylovWorkspaceOptionsC,
                           ws_out :: Ptr{Ptr{Cvoid}})
  mem = wopts.memory == 0 ? 5 : Int(wopts.memory)
  if solver_int == Cint(0) && dtype_int == Cint(0)
    ws = Krylov.BlockGmresWorkspace(Int(m), Int(n), Int(p), Vector{Float32}, Matrix{Float32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_block_gmres_f32[r] = ws; block_ws_key_store[r] = 0x00
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(1)
    ws = Krylov.BlockGmresWorkspace(Int(m), Int(n), Int(p), Vector{Float64}, Matrix{Float64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_block_gmres_f64[r] = ws; block_ws_key_store[r] = 0x01
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(2)
    ws = Krylov.BlockGmresWorkspace(Int(m), Int(n), Int(p), Vector{ComplexF32}, Matrix{ComplexF32}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_block_gmres_cf32[r] = ws; block_ws_key_store[r] = 0x02
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(0) && dtype_int == Cint(3)
    ws = Krylov.BlockGmresWorkspace(Int(m), Int(n), Int(p), Vector{ComplexF64}, Matrix{ComplexF64}; memory = mem)
    r  = Base.pointer_from_objref(ws)
    store_block_gmres_cf64[r] = ws; block_ws_key_store[r] = 0x03
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(0)
    ws = Krylov.BlockMinresWorkspace(Int(m), Int(n), Int(p), Vector{Float32}, Matrix{Float32})
    r  = Base.pointer_from_objref(ws)
    store_block_minres_f32[r] = ws; block_ws_key_store[r] = 0x04
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(1)
    ws = Krylov.BlockMinresWorkspace(Int(m), Int(n), Int(p), Vector{Float64}, Matrix{Float64})
    r  = Base.pointer_from_objref(ws)
    store_block_minres_f64[r] = ws; block_ws_key_store[r] = 0x05
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(2)
    ws = Krylov.BlockMinresWorkspace(Int(m), Int(n), Int(p), Vector{ComplexF32}, Matrix{ComplexF32})
    r  = Base.pointer_from_objref(ws)
    store_block_minres_cf32[r] = ws; block_ws_key_store[r] = 0x06
    unsafe_store!(ws_out, r)
  elseif solver_int == Cint(1) && dtype_int == Cint(3)
    ws = Krylov.BlockMinresWorkspace(Int(m), Int(n), Int(p), Vector{ComplexF64}, Matrix{ComplexF64})
    r  = Base.pointer_from_objref(ws)
    store_block_minres_cf64[r] = ws; block_ws_key_store[r] = 0x07
    unsafe_store!(ws_out, r)
  else
    return Cint(-2)  # unknown (block solver, dtype) combination
  end
  Cint(0)
end
