Skip to content

Commit 6ab392f

Browse files
committed
Use dimension_names instead of static_fieldnames
1 parent 6c01814 commit 6ab392f

File tree

5 files changed

+31
-18
lines changed

5 files changed

+31
-18
lines changed

docs/src/types.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ UnionAbstractQuantity
4444
DynamicQuantities.ABSTRACT_QUANTITY_TYPES
4545
```
4646

47-
## Constructors
47+
## Custom behavior in abstract quantities
48+
49+
There are a few functions you may need to overload
50+
when subtyping `AbstractDimensions`, `AbstractQuantity`,
51+
or `AbstractGenericQuantity`.
4852

4953
```@docs
5054
constructorof
5155
with_type_parameters
52-
```
56+
dimension_names
57+
```

src/internal_utils.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ This file contains utility functions that are not specific to the
33
library, but are used throughout.
44
"""
55

6-
@generated function fieldnames_equal(::Type{T1}, ::Type{T2}) where {T1,T2}
7-
# Needs to be a generated function to ensure hardcoded
8-
return Base.propertynames(T1) == Base.propertynames(T2)
9-
end
10-
116
const SUPERSCRIPT_MAPPING = ('', '¹', '²', '³', '', '', '', '', '', '')
127
const INTCHARS = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
138

src/symbolic_dimensions.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Tricks: static_fieldnames
2-
31
import .Units: UNIT_SYMBOLS, UNIT_MAPPING, UNIT_VALUES
42
import .Constants: CONSTANT_SYMBOLS, CONSTANT_MAPPING, CONSTANT_VALUES
53

@@ -41,7 +39,7 @@ struct SymbolicDimensions{R} <: AbstractDimensions{R}
4139
nzvals::Vector{R}
4240
end
4341

44-
static_fieldnames(::Type{<:SymbolicDimensions}) = ALL_SYMBOLS
42+
@inline dimension_names(::Type{<:SymbolicDimensions}) = ALL_SYMBOLS
4543
function Base.getproperty(d::SymbolicDimensions{R}, s::Symbol) where {R}
4644
nzdims = getfield(d, :nzdims)
4745
i = get(ALL_MAPPING, s, INDEX_TYPE(0))

src/types.jl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Tricks: static_fieldnames, static_fieldtypes
1+
using Tricks: static_fieldnames
22

33
const DEFAULT_DIM_BASE_TYPE = FixedRational{DEFAULT_NUMERATOR_TYPE,DEFAULT_DENOM}
44
const DEFAULT_VALUE_TYPE = Float64
@@ -103,13 +103,13 @@ struct Dimensions{R<:Real} <: AbstractDimensions{R}
103103
amount::R
104104
end
105105

106-
(::Type{D})(::Type{R}; kws...) where {R,D<:AbstractDimensions} = with_type_parameters(D, R)((tryrationalize(R, get(kws, k, zero(R))) for k in static_fieldnames(D))...)
106+
(::Type{D})(::Type{R}; kws...) where {R,D<:AbstractDimensions} = with_type_parameters(D, R)((tryrationalize(R, get(kws, k, zero(R))) for k in dimension_names(D))...)
107107
(::Type{D})(; kws...) where {R,D<:AbstractDimensions{R}} = constructorof(D)(R; kws...)
108108
(::Type{D})(; kws...) where {D<:AbstractDimensions} = D(DEFAULT_DIM_BASE_TYPE; kws...)
109109
function (::Type{D})(d::D2) where {R,D<:AbstractDimensions{R},D2<:AbstractDimensions}
110-
fieldnames_equal(D, D2) ||
110+
dimension_names_equal(D, D2) ||
111111
error("Cannot create a dimensions of `$(D)` from `$(D2)`. Please write a custom method for construction.")
112-
D((getproperty(d, k) for k in static_fieldnames(D))...)
112+
D((getproperty(d, k) for k in dimension_names(D))...)
113113
end
114114

115115
const DEFAULT_DIM_TYPE = Dimensions{DEFAULT_DIM_BASE_TYPE}
@@ -238,6 +238,17 @@ function with_type_parameters(::Type{Q}, ::Type{T}, ::Type{D}) where {Q<:UnionAb
238238
return constructorof(Q){T,D}
239239
end
240240

241+
"""
242+
dimension_names(::Type{<:AbstractDimensions})
243+
244+
Return a tuple of symbols with the names of the dimensions of the given type.
245+
This should be static so that it can be hardcoded during compilation.
246+
The default is to use `fieldnames`, but you can overload this for custom behavior.
247+
"""
248+
@inline function dimension_names(::Type{D}) where {D<:AbstractDimensions}
249+
return static_fieldnames(D)
250+
end
251+
241252
struct DimensionError{Q1,Q2} <: Exception
242253
q1::Q1
243254
q2::Q2

src/utils.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import Compat: allequal
2-
import Tricks: static_fieldnames
32

43
function map_dimensions(f::F, args::AbstractDimensions...) where {F<:Function}
54
dimension_type = promote_type(typeof(args).parameters...)
6-
dimension_names = static_fieldnames(dimension_type)
5+
dim_names = dimension_names(dimension_type)
76
return new_dimensions(
87
dimension_type,
98
(
109
f((getproperty(arg, dim) for arg in args)...)
11-
for dim in dimension_names
10+
for dim in dim_names
1211
)...
1312
)
1413
end
@@ -48,9 +47,14 @@ function Base.promote_rule(::Type{<:AbstractQuantity}, ::Type{<:Number})
4847
return Number
4948
end
5049

51-
Base.keys(d::AbstractDimensions) = static_fieldnames(typeof(d))
50+
Base.keys(d::AbstractDimensions) = dimension_names(typeof(d))
5251
Base.getindex(d::AbstractDimensions, k::Symbol) = getfield(d, k)
5352

53+
@generated function dimension_names_equal(::Type{T1}, ::Type{T2}) where {T1,T2}
54+
# Needs to be a generated function to ensure hardcoded
55+
return dimension_names(T1) == dimension_names(T2)
56+
end
57+
5458
# Compatibility with `.*`
5559
Base.size(q::UnionAbstractQuantity) = size(ustrip(q))
5660
Base.length(q::UnionAbstractQuantity) = length(ustrip(q))

0 commit comments

Comments
 (0)