Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.82 KB | None | 0 0
  1. using Base: uniontypes
  2.  
  3. """
  4. is_type_stable(fn, argtypes)
  5.  
  6. `fn` returns values of a stable type
  7.  
  8. if `is_type_stable(fn, argtypes)`
  9. then `y = fn(args)` supports fast dispatch on `y`
  10. """
  11. function is_type_stable(fn, argtypes::Tuple)
  12. arg_types = typed_as_tuple(argtypes)
  13. rtn_type = Base.return_types(fn, arg_types)[1]
  14. return isconcretetype(rtn_type)
  15. end
  16.  
  17. is_type_stable(fn, argtype) = is_type_stable(fn, (argtype,))
  18. is_type_stable(fn) = is_type_stable(fn, ())
  19.  
  20.  
  21. #=
  22. To permit the composed return types `Union{Nothing, Type}`, `Union{Missing, Type}`
  23. to resolve supporting fast dispatch, where Type may be a Union of two `isbitstype` types,
  24. set `FastDispatchMax = 2`. Otherwise set `FastDispatchMax = 3`.
  25. =#
  26.  
  27. """
  28. FastDispatchMax
  29.  
  30. `is_type_stablish(fn, argtypes)` is true if `is_type_stable(fn, argtypes)` or
  31. if the type returned is a Union of no more than this many `isbitstype` types.
  32. """
  33. const FastDispatchMax = 2
  34.  
  35. """
  36. is_type_stablish(fn, argtypes; fastdispatch::Int=FastDispatchMax)
  37.  
  38. `fn` returns values of a stable type, or
  39. `fn` returns values from a Union of `FastDispatchMax` many `isbitstype` types
  40.  
  41. if `is_type_stablish(fn, argtypes)` then `y = fn(args)` supports fast dispatch on `y`
  42. """
  43. function is_type_stablish(fn, argtypes::Tuple; fastdispatch::Int=FastDispatchMax)
  44. arg_types = Tuple_from_typestuple(argtypes)
  45. rtn_type = Base.return_types(fn, arg_types)[1]
  46. if isa(rtn_type, Union)
  47. (tallytypes(rtn_type) > fastdispatch) && return false
  48. all(isbitstype.(uniontypes(rtn_type))) || return false
  49. elseif isa(rtn_type,Tuple)
  50. for item in tupletypes(rtn_type)
  51. ((isa(item, Union) && tallytypes(item) > fastdispatch) || !isbitstype(item)) && return false
  52. end
  53. else
  54. return isconcretetype(rtn_type)
  55. end
  56. end
  57.  
  58. is_type_stablish(fn, argtype) = is_type_stablish(fn, (argtype,))
  59. is_type_stablish(fn) = is_type_stablish(fn, ())
  60.  
  61. """
  62. Tuple_from_typestuple
  63.  
  64. converts a tuple (`(Int64, String)`) to a Tuple (`Tuple{Int64, String}`)
  65. """
  66. Tuple_from_typestuple(items::NTuple{N,T}) where {T,N} = Tuple{items...,}
  67. Tuple_from_typestuple() = Tuple{}
  68.  
  69. """
  70. tuple_types
  71.  
  72. obtain the values in a Tuple (`Tuple{Int64, String}`) as a tuple (`(Int64, String)`)
  73. """
  74. tuple_types(::Type{T}) where {T<:Tuple} = (T.parameters...,)
  75.  
  76. """
  77. union_types
  78.  
  79. obtain the types in a Union (`Union{Int64, String}`) as a tuple (`(Int64, String)`)
  80. """
  81. union_types(x::Union) = (Base.uniontypes(x)...,)
  82.  
  83. """
  84. tally_types(x::Union)
  85.  
  86. count the types in a Union (`Union{Int64, String}` ==> 2)
  87. count the types in a Tuple (`Tuple{Int64, String}` ==> 2)
  88. """
  89. tally_types(x::Union) = length(union_types(x))
  90. tally_types(x::Tuple) = length(tuple_types(x))
  91.  
  92. # end of typestable.jl
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement