11module Units
22
3+ import .. WriteOnceReadMany
34import .. DEFAULT_DIM_TYPE
45import .. DEFAULT_VALUE_TYPE
56import .. DEFAULT_QUANTITY_TYPE
67
78@assert DEFAULT_VALUE_TYPE == Float64 " `units.jl` must be updated to support a different default value type."
89
9- const _UNIT_SYMBOLS = Symbol[]
10- const _UNIT_VALUES = DEFAULT_QUANTITY_TYPE[]
10+ const UNIT_SYMBOLS = WriteOnceReadMany {Vector{ Symbol}} ()
11+ const UNIT_VALUES = WriteOnceReadMany {Vector{ DEFAULT_QUANTITY_TYPE}} ()
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
2425 const $ name = $ value
25- push! (_UNIT_SYMBOLS, Symbol ( $ s) )
26- push! (_UNIT_VALUES , $ name)
26+ push! ($ UNIT_SYMBOLS, $ name_symbol )
27+ push! ($ UNIT_VALUES , $ name)
2728 end
2829end
2930
@@ -42,13 +43,13 @@ function _add_prefixes(base_unit::Symbol, prefixes, register_function)
4243end
4344
4445# 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 )
46+ @_lazy_register_unit m DEFAULT_QUANTITY_TYPE (1.0 , length= 1 )
47+ @_lazy_register_unit g DEFAULT_QUANTITY_TYPE (1e-3 , mass= 1 )
48+ @_lazy_register_unit s DEFAULT_QUANTITY_TYPE (1.0 , time= 1 )
49+ @_lazy_register_unit A DEFAULT_QUANTITY_TYPE (1.0 , current= 1 )
50+ @_lazy_register_unit K DEFAULT_QUANTITY_TYPE (1.0 , temperature= 1 )
51+ @_lazy_register_unit cd DEFAULT_QUANTITY_TYPE (1.0 , luminosity= 1 )
52+ @_lazy_register_unit mol DEFAULT_QUANTITY_TYPE (1.0 , amount= 1 )
5253
5354@add_prefixes m (f, p, n, μ, u, c, d, m, k, M, G)
5455@add_prefixes g (p, n, μ, u, m, k)
8889)
8990
9091# 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)
92+ @_lazy_register_unit Hz inv (s)
93+ @_lazy_register_unit N kg * m / s^ 2
94+ @_lazy_register_unit Pa N / m^ 2
95+ @_lazy_register_unit J N * m
96+ @_lazy_register_unit W J / s
97+ @_lazy_register_unit C A * s
98+ @_lazy_register_unit V W / A
99+ @_lazy_register_unit F C / V
100+ @_lazy_register_unit Ω V / A
101+ @_lazy_register_unit ohm Ω
102+ @_lazy_register_unit T N / (A * m)
102103
103104@add_prefixes Hz (n, μ, u, m, k, M, G)
104105@add_prefixes N ()
@@ -156,17 +157,17 @@ end
156157
157158# Common assorted units
158159# # 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
160+ @_lazy_register_unit min 60 * s
161+ @_lazy_register_unit minute min
162+ @_lazy_register_unit h 60 * min
163+ @_lazy_register_unit hr h
164+ @_lazy_register_unit day 24 * h
165+ @_lazy_register_unit d day
166+ @_lazy_register_unit wk 7 * day
167+ @_lazy_register_unit yr 365.25 * day
168+ @_lazy_register_unit inch 2.54 * cm
169+ @_lazy_register_unit ft 12 * inch
170+ @_lazy_register_unit mi 5280 * ft
170171
171172@add_prefixes min ()
172173@add_prefixes minute ()
178179@add_prefixes yr (k, M, G)
179180
180181# # Volume
181- @register_unit L dm^ 3
182+ @_lazy_register_unit L dm^ 3
182183
183184@add_prefixes L (μ, u, m, c, d)
184185
188189)
189190
190191# # Pressure
191- @register_unit bar 100 * kPa
192+ @_lazy_register_unit bar 100 * kPa
192193
193194@add_prefixes bar (m,)
194195
203204# Do not wish to define physical constants, as the number of symbols might lead to ambiguity.
204205# The user should define these instead.
205206
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)])
207+ # Update `UNIT_MAPPING` with all internally defined unit symbols.
208+ const UNIT_MAPPING = WriteOnceReadMany (Dict (s => i for (i, s) in enumerate (UNIT_SYMBOLS)))
210209
211210end
0 commit comments