@@ -6,24 +6,35 @@ import ..DEFAULT_QUANTITY_TYPE
66
77@assert DEFAULT_VALUE_TYPE == Float64 " `units.jl` must be updated to support a different default value type."
88
9- const _UNIT_SYMBOLS = Symbol[]
10- const _UNIT_VALUES = DEFAULT_QUANTITY_TYPE[]
9+ const UNIT_SYMBOLS = Symbol[]
10+ const UNIT_VALUES = DEFAULT_QUANTITY_TYPE[]
1111
1212macro register_unit (name, value)
1313 return esc (_register_unit (name, value))
1414end
1515
16+ macro _lazy_register_unit (name, value)
17+ return esc (_register_unit (name, value; lazy = true ))
18+ end
19+
1620macro add_prefixes (base_unit, prefixes)
1721 @assert prefixes. head == :tuple
1822 return esc (_add_prefixes (base_unit, prefixes. args, _register_unit))
1923end
2024
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)
2332 return quote
33+ haskey ($ UNIT_MAPPING, $ name_symbol) && throw (" Unit $name_symbol already exists." )
2434 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)
2738 end
2839end
2940
@@ -42,13 +53,13 @@ function _add_prefixes(base_unit::Symbol, prefixes, register_function)
4253end
4354
4455# 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 )
5263
5364@add_prefixes m (f, p, n, μ, u, c, d, m, k, M, G)
5465@add_prefixes g (p, n, μ, u, m, k)
8899)
89100
90101# 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)
102113
103114@add_prefixes Hz (n, μ, u, m, k, M, G)
104115@add_prefixes N ()
@@ -156,17 +167,17 @@ end
156167
157168# Common assorted units
158169# # 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
170181
171182@add_prefixes min ()
172183@add_prefixes minute ()
178189@add_prefixes yr (k, M, G)
179190
180191# # Volume
181- @register_unit L dm^ 3
192+ @_lazy_register_unit L dm^ 3
182193
183194@add_prefixes L (μ, u, m, c, d)
184195
203214# Do not wish to define physical constants, as the number of symbols might lead to ambiguity.
204215# The user should define these instead.
205216
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)))
210219
211220end
0 commit comments