-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathcone_dispatch.jl
47 lines (41 loc) · 2.12 KB
/
cone_dispatch.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#-----------------------------------------------------
# macro for circumventing runtime dynamic dispatch
# on AbstractCones and trying to force a jumptable
# structure instead. Must wrap a call to a function
# with an argument explicitly named "cone", and constructs
# a big if/else table testing the type of cone against
# the subtypes of AbstractCone
# -----------------------------------------------------
# macro dispatch won't work unless each cone type is completely specified, i.e.
# we can't dispatch statically on the non-concrete types PowerCone{T} or
# ExponentialCone{T}. So we first need a way to expand each AbstractCone{T}
# to its complete type, including the extra parameters in the exp / power cones
# None if this would be necessary if StaticArrays could write to MArrays
# with non-isbits types. See here:
# https://github.com/JuliaArrays/StaticArrays.jl/pull/749
# If the PR is accepted then the type dependent vector and matrix types
# defined in CONE3D_M3T_TYPE and CONE3D_V3T_TYPE could be dropped,
# and ExponentialCone and PowerCone would no longer need hidden
#internal parameters with outer-only constructors.
# turns PowerCone{T} to PowerCone{T,M3T,V3T}
function _make_conetype_concrete(::Type{PowerCone},T::Type)
return PowerCone{T,CONE3D_M3T_TYPE(T),CONE3D_V3T_TYPE(T)}
end
# turns ExponentialCone{T} to ExponentialCone{T,M3T,V3T}
function _make_conetype_concrete(::Type{ExponentialCone},T::Type)
return ExponentialCone{T,CONE3D_M3T_TYPE(T),CONE3D_V3T_TYPE(T)}
end
# turns any other AbstractCone{T} to itself
_make_conetype_concrete(conetype,T::Type) = conetype{T}
function _conedispatch(x, call)
# We do not set thetypes = subtypes(AbstractCone), but
# rather to entries in our dictionary of primitive cone
# types. This avoids adding CompositeCone itself to the
# switchyard we construct here, but would also prevent
# the use of nested CompositeCones.
thetypes = collect(values(ConeDict))
foldr((t, tail) -> :(if $x isa _make_conetype_concrete($t,T); $call else $tail end), thetypes, init=Expr(:block))
end
macro conedispatch(call)
esc(_conedispatch(:cone, call))
end