EltypeExtensions.jl is a mini toolbox for eltype-related conversions. The motivation of this package comes from manipulating (nested) arrays with different eltypes. However if you have any reasonable idea that works on other instances, feel free to write an issue/pull request.
We note that this package has some overlap with TypeUtils.jl and Unitless.jl.
The package is tested against [Julia versions from 1.0 to 1.11]
X[ubuntu, windows, macOS]
X[x64]
.
convert_eltype(T, x)
works like convert(T, x)
, except that T
refers to the eltype of the result. This can be useful for generic codes.
It should be always true that convert_eltype(T, x) isa _to_eltype(T, typeof(x))
. However, since convert_eltype
and _to_eltype
use different routines, it's possible that the equality doesn't hold for some types. Please submit an issue or PR if that happens.
If typeof(x)
is not in Base or stdlib, the package who owns the type should implement corresponding _to_eltype
or convert_eltype
. convert_eltype
has fallbacks, in which case it could be unnecessary:
- For a subtype of
AbstractArray
,convert_eltype
calls the constructorAbstractArray{T}
and_to_eltype
returnsArray
. - For a subtype of
AbstractUnitRange
,convert_eltype
calls the constructorAbstractUnitRange{T}
. - For a subtype of
AbstractRange
,convert_eltype
uses broadcast throughmap
. - For a
Tuple
,convert_eltype
uses dot broadcast. - For other types,
convert_eltype
callsconvert
and_to_eltype
.
However, _to_eltype
must be implemented for each type to support convert_basetype
and convert_precisiontype
. The following types from Base and stdlib are explicitly supported by _to_eltype
:
AbstractArray, AbstractDict, AbstractSet, Adjoint, Bidiagonal, BitArray,
CartesianIndices, Diagonal, Dict, Hermitian, Set, StepRangeLen, Symmetric,
SymTridiagonal, Transpose, TwicePrecision, UnitRange
The basetype
is used for nested collections, where eltype
is repeatedly applied until the bottom. precisiontype
has a similar idea, but goes deeper when possible. precisiontype
is used to manipulate the accuracy of (nested) collections.
sometype(T)
gets thesometype
of typeT
.sometype(x) = sometype(typeof(x))
is also provided for convenience._to_sometype(T,S)
converts the typeS
to have thesometype
ofT
.convert_sometype(T,A)
convertsA
to have thesometype
ofT
.
where some
can be el
, base
and precision
.
convert_precisiontype
accepts an optional third argument prec
.
- When
T
has static precision,prec
has no effect. - When
T
has dynamic precision,prec
specifies the precision of conversion. Whenprec
is not provided, the precision is decided by the external setup fromT
. The difference is significant whenconvert_precisiontype
is called by another function. See the document for an example. - When
T
is an integer, the conversion will dig intoRational
as well. In contrast, sinceRational
as a whole is more "precise" than an integer,precisiontype
doesn't unwrapRational
.