@@ -6,27 +6,30 @@ 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[]
11+ const UNIT_MAPPING = Dict {Symbol,Int} ()
1112
12- macro register_unit (name, value)
13- return esc (_register_unit (name, value))
13+ macro _lazy_register_unit (name, value)
14+ return esc (_lazy_register_unit (name, value))
1415end
1516
1617macro add_prefixes (base_unit, prefixes)
1718 @assert prefixes. head == :tuple
18- return esc (_add_prefixes (base_unit, prefixes. args, _register_unit ))
19+ return esc (_add_prefixes (base_unit, prefixes. args, _lazy_register_unit ))
1920end
2021
21- function _register_unit (name:: Symbol , value)
22- s = string (name)
23- return quote
22+ function _lazy_register_unit (name:: Symbol , value)
23+ name_symbol = Meta. quot (name)
24+ quote
25+ haskey ($ UNIT_MAPPING, $ name_symbol) && throw (" Unit $($ name_symbol) already exists." )
2426 const $ name = $ value
25- push! (_UNIT_SYMBOLS, Symbol ( $ s) )
26- push! (_UNIT_VALUES , $ name)
27+ push! ($ UNIT_SYMBOLS, $ name_symbol )
28+ push! ($ UNIT_VALUES , $ name)
2729 end
2830end
2931
32+
3033function _add_prefixes (base_unit:: Symbol , prefixes, register_function)
3134 all_prefixes = (
3235 f= 1e-15 , p= 1e-12 , n= 1e-9 , μ= 1e-6 , u= 1e-6 , m= 1e-3 , c= 1e-2 , d= 1e-1 ,
@@ -42,13 +45,13 @@ function _add_prefixes(base_unit::Symbol, prefixes, register_function)
4245end
4346
4447# 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 )
48+ @_lazy_register_unit m DEFAULT_QUANTITY_TYPE (1.0 , length = 1 )
49+ @_lazy_register_unit g DEFAULT_QUANTITY_TYPE (1e-3 , mass = 1 )
50+ @_lazy_register_unit s DEFAULT_QUANTITY_TYPE (1.0 , time = 1 )
51+ @_lazy_register_unit A DEFAULT_QUANTITY_TYPE (1.0 , current = 1 )
52+ @_lazy_register_unit K DEFAULT_QUANTITY_TYPE (1.0 , temperature = 1 )
53+ @_lazy_register_unit cd DEFAULT_QUANTITY_TYPE (1.0 , luminosity = 1 )
54+ @_lazy_register_unit mol DEFAULT_QUANTITY_TYPE (1.0 , amount = 1 )
5255
5356@add_prefixes m (f, p, n, μ, u, c, d, m, k, M, G)
5457@add_prefixes g (p, n, μ, u, m, k)
8891)
8992
9093# 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)
94+ @_lazy_register_unit Hz inv (s)
95+ @_lazy_register_unit N kg * m / s^ 2
96+ @_lazy_register_unit Pa N / m^ 2
97+ @_lazy_register_unit J N * m
98+ @_lazy_register_unit W J / s
99+ @_lazy_register_unit C A * s
100+ @_lazy_register_unit V W / A
101+ @_lazy_register_unit F C / V
102+ @_lazy_register_unit Ω V / A
103+ @_lazy_register_unit ohm Ω
104+ @_lazy_register_unit T N / (A * m)
102105
103106@add_prefixes Hz (n, μ, u, m, k, M, G)
104107@add_prefixes N ()
@@ -156,17 +159,17 @@ end
156159
157160# Common assorted units
158161# # 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
162+ @_lazy_register_unit min 60 * s
163+ @_lazy_register_unit minute min
164+ @_lazy_register_unit h 60 * min
165+ @_lazy_register_unit hr h
166+ @_lazy_register_unit day 24 * h
167+ @_lazy_register_unit d day
168+ @_lazy_register_unit wk 7 * day
169+ @_lazy_register_unit yr 365.25 * day
170+ @_lazy_register_unit inch 2.54 * cm
171+ @_lazy_register_unit ft 12 * inch
172+ @_lazy_register_unit mi 5280 * ft
170173
171174@add_prefixes min ()
172175@add_prefixes minute ()
178181@add_prefixes yr (k, M, G)
179182
180183# # Volume
181- @register_unit L dm^ 3
184+ @_lazy_register_unit L dm^ 3
182185
183186@add_prefixes L (μ, u, m, c, d)
184187
188191)
189192
190193# # Pressure
191- @register_unit bar 100 * kPa
194+ @_lazy_register_unit bar 100 * kPa
192195
193196@add_prefixes bar (m,)
194197
203206# Do not wish to define physical constants, as the number of symbols might lead to ambiguity.
204207# The user should define these instead.
205208
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)])
209+ # Update `UNIT_MAPPING` with all internally defined unit symbols.
210+ merge! (UNIT_MAPPING, Dict (UNIT_SYMBOLS .=> 1 : lastindex (UNIT_SYMBOLS)))
210211
211212end
0 commit comments