@@ -6,24 +6,35 @@ import ..DEFAULT_QUANTITY_TYPE
6
6
7
7
@assert DEFAULT_VALUE_TYPE == Float64 " `units.jl` must be updated to support a different default value type."
8
8
9
- const _UNIT_SYMBOLS = Symbol[]
10
- const _UNIT_VALUES = DEFAULT_QUANTITY_TYPE[]
9
+ const UNIT_SYMBOLS = Symbol[]
10
+ const UNIT_VALUES = DEFAULT_QUANTITY_TYPE[]
11
11
12
12
macro register_unit (name, value)
13
13
return esc (_register_unit (name, value))
14
14
end
15
15
16
+ macro _lazy_register_unit (name, value)
17
+ return esc (_register_unit (name, value; lazy = true ))
18
+ end
19
+
16
20
macro add_prefixes (base_unit, prefixes)
17
21
@assert prefixes. head == :tuple
18
22
return esc (_add_prefixes (base_unit, prefixes. args, _register_unit))
19
23
end
20
24
21
- function _register_unit (name:: Symbol , value)
22
- s = string (name)
25
+ const UNIT_MAPPING = Dict {Symbol,Int} ()
26
+ function update_unit_mapping (name, value, unit_mapping:: Dict{Symbol, Int} = UNIT_MAPPING)
27
+ unit_mapping[name] = length (unit_mapping) + 1
28
+ end
29
+
30
+ function _register_unit (name:: Symbol , value; lazy = false )
31
+ name_symbol = Meta. quot (name)
23
32
return quote
33
+ haskey ($ UNIT_MAPPING, $ name_symbol) && throw (" Unit $name_symbol already exists." )
24
34
const $ name = $ value
25
- push! (_UNIT_SYMBOLS, Symbol ($ s))
26
- push! (_UNIT_VALUES, $ name)
35
+ push! ($ UNIT_SYMBOLS, $ name_symbol)
36
+ push! ($ UNIT_VALUES, $ name)
37
+ ! $ lazy && $ update_unit_mapping ($ name_symbol, $ value)
27
38
end
28
39
end
29
40
@@ -42,13 +53,13 @@ function _add_prefixes(base_unit::Symbol, prefixes, register_function)
42
53
end
43
54
44
55
# SI base units
45
- @register_unit m DEFAULT_QUANTITY_TYPE (1.0 , length= 1 )
46
- @register_unit g DEFAULT_QUANTITY_TYPE (1e-3 , mass= 1 )
47
- @register_unit s DEFAULT_QUANTITY_TYPE (1.0 , time= 1 )
48
- @register_unit A DEFAULT_QUANTITY_TYPE (1.0 , current= 1 )
49
- @register_unit K DEFAULT_QUANTITY_TYPE (1.0 , temperature= 1 )
50
- @register_unit cd DEFAULT_QUANTITY_TYPE (1.0 , luminosity= 1 )
51
- @register_unit mol DEFAULT_QUANTITY_TYPE (1.0 , amount= 1 )
56
+ @_lazy_register_unit m DEFAULT_QUANTITY_TYPE (1.0 , length = 1 )
57
+ @_lazy_register_unit g DEFAULT_QUANTITY_TYPE (1e-3 , mass = 1 )
58
+ @_lazy_register_unit s DEFAULT_QUANTITY_TYPE (1.0 , time = 1 )
59
+ @_lazy_register_unit A DEFAULT_QUANTITY_TYPE (1.0 , current = 1 )
60
+ @_lazy_register_unit K DEFAULT_QUANTITY_TYPE (1.0 , temperature = 1 )
61
+ @_lazy_register_unit cd DEFAULT_QUANTITY_TYPE (1.0 , luminosity = 1 )
62
+ @_lazy_register_unit mol DEFAULT_QUANTITY_TYPE (1.0 , amount = 1 )
52
63
53
64
@add_prefixes m (f, p, n, μ, u, c, d, m, k, M, G)
54
65
@add_prefixes g (p, n, μ, u, m, k)
88
99
)
89
100
90
101
# SI derived units
91
- @register_unit Hz inv (s)
92
- @register_unit N kg * m / s^ 2
93
- @register_unit Pa N / m^ 2
94
- @register_unit J N * m
95
- @register_unit W J / s
96
- @register_unit C A * s
97
- @register_unit V W / A
98
- @register_unit F C / V
99
- @register_unit Ω V / A
100
- @register_unit ohm Ω
101
- @register_unit T N / (A * m)
102
+ @_lazy_register_unit Hz inv (s)
103
+ @_lazy_register_unit N kg * m / s^ 2
104
+ @_lazy_register_unit Pa N / m^ 2
105
+ @_lazy_register_unit J N * m
106
+ @_lazy_register_unit W J / s
107
+ @_lazy_register_unit C A * s
108
+ @_lazy_register_unit V W / A
109
+ @_lazy_register_unit F C / V
110
+ @_lazy_register_unit Ω V / A
111
+ @_lazy_register_unit ohm Ω
112
+ @_lazy_register_unit T N / (A * m)
102
113
103
114
@add_prefixes Hz (n, μ, u, m, k, M, G)
104
115
@add_prefixes N ()
@@ -156,17 +167,17 @@ end
156
167
157
168
# Common assorted units
158
169
# # Time
159
- @register_unit min 60 * s
160
- @register_unit minute min
161
- @register_unit h 60 * min
162
- @register_unit hr h
163
- @register_unit day 24 * h
164
- @register_unit d day
165
- @register_unit wk 7 * day
166
- @register_unit yr 365.25 * day
167
- @register_unit inch 2.54 * cm
168
- @register_unit ft 12 * inch
169
- @register_unit mi 5280 * ft
170
+ @_lazy_register_unit min 60 * s
171
+ @_lazy_register_unit minute min
172
+ @_lazy_register_unit h 60 * min
173
+ @_lazy_register_unit hr h
174
+ @_lazy_register_unit day 24 * h
175
+ @_lazy_register_unit d day
176
+ @_lazy_register_unit wk 7 * day
177
+ @_lazy_register_unit yr 365.25 * day
178
+ @_lazy_register_unit inch 2.54 * cm
179
+ @_lazy_register_unit ft 12 * inch
180
+ @_lazy_register_unit mi 5280 * ft
170
181
171
182
@add_prefixes min ()
172
183
@add_prefixes minute ()
178
189
@add_prefixes yr (k, M, G)
179
190
180
191
# # Volume
181
- @register_unit L dm^ 3
192
+ @_lazy_register_unit L dm^ 3
182
193
183
194
@add_prefixes L (μ, u, m, c, d)
184
195
203
214
# Do not wish to define physical constants, as the number of symbols might lead to ambiguity.
204
215
# The user should define these instead.
205
216
206
- """ A tuple of all possible unit symbols."""
207
- const UNIT_SYMBOLS = Tuple (_UNIT_SYMBOLS)
208
- const UNIT_VALUES = Tuple (_UNIT_VALUES)
209
- const UNIT_MAPPING = NamedTuple ([s => i for (i, s) in enumerate (UNIT_SYMBOLS)])
217
+ """ Update `UNIT_MAPPING` with all internally defined unit symbols."""
218
+ merge! (UNIT_MAPPING, Dict (UNIT_SYMBOLS .=> 1 : lastindex (UNIT_SYMBOLS)))
210
219
211
220
end
0 commit comments