Skip to content

Commit 507b456

Browse files
feat: allow inbounds getters and setters
1 parent ec17278 commit 507b456

File tree

6 files changed

+1060
-738
lines changed

6 files changed

+1060
-738
lines changed

src/parameter_indexing.jl

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,19 @@ apply:
3434
parameter values, and can be accessed at specific indices in the timeseries.
3535
- A mix of timeseries and non-timeseries parameters: The function can _only_ be used on
3636
non-timeseries objects and will return the value of each parameter at in the object.
37+
38+
# Keyword Arguments
39+
40+
- `inbounds`: Whether to wrap the returned function in `@inbounds`.
3741
"""
38-
function getp(sys, p)
42+
function getp(sys, p; inbounds = false)
3943
symtype = symbolic_type(p)
4044
elsymtype = symbolic_type(eltype(p))
41-
_getp(sys, symtype, elsymtype, p)
45+
getter = _getp(sys, symtype, elsymtype, p)
46+
if inbounds
47+
getter = InboundsWrapper(getter)
48+
end
49+
return getter
4250
end
4351

4452
struct GetParameterIndex{I} <: AbstractParameterGetIndexer
@@ -659,15 +667,22 @@ Requires that the value provider implement [`parameter_values`](@ref) and the re
659667
collection be a mutable reference to the parameter object. In case `parameter_values`
660668
cannot return such a mutable reference, or additional actions need to be performed when
661669
updating parameters, [`set_parameter!`](@ref) must be implemented.
670+
671+
# Keyword Arguments
672+
673+
- `inbounds`: Whether to wrap the function in `@inbounds`.
662674
"""
663-
function setp(sys, p; run_hook = true)
675+
function setp(sys, p; run_hook = true, inbounds = false)
664676
symtype = symbolic_type(p)
665677
elsymtype = symbolic_type(eltype(p))
666-
return if run_hook
667-
return ParameterHookWrapper(_setp(sys, symtype, elsymtype, p), p)
668-
else
669-
_setp(sys, symtype, elsymtype, p)
678+
setter = _setp(sys, symtype, elsymtype, p)
679+
if run_hook
680+
setter = ParameterHookWrapper(setter, p)
681+
end
682+
if inbounds
683+
setter = InboundsWrapper(setter)
670684
end
685+
return setter
671686
end
672687

673688
struct SetParameterIndex{I} <: AbstractSetIndexer
@@ -723,11 +738,19 @@ the types of values stored, and leverages [`remake_buffer`](@ref). Note that `sy
723738
an index, a symbolic variable, or an array/tuple of the aforementioned.
724739
725740
Requires that the value provider implement `parameter_values` and `remake_buffer`.
741+
742+
# Keyword Arguments
743+
744+
- `inbounds`: Whether to wrap the returned function in `@inbounds`.
726745
"""
727-
function setp_oop(indp, sym)
746+
function setp_oop(indp, sym; inbounds = false)
728747
symtype = symbolic_type(sym)
729748
elsymtype = symbolic_type(eltype(sym))
730-
return _setp_oop(indp, symtype, elsymtype, sym)
749+
setter = _setp_oop(indp, symtype, elsymtype, sym)
750+
if inbounds
751+
setter = InboundsWrapper(setter)
752+
end
753+
return setter
731754
end
732755

733756
function _setp_oop(indp, ::NotSymbolic, ::NotSymbolic, sym)

src/state_indexing.jl

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,19 @@ relying on the above functions.
2424
If the value provider is a parameter timeseries object, the same rules apply as
2525
[`getp`](@ref). The difference here is that `sym` may also contain non-parameter symbols,
2626
and the values are always returned corresponding to the state timeseries.
27+
28+
# Keyword Arguments
29+
30+
- `inbounds`: whether to wrap the returned function in an `@inbounds`.
2731
"""
28-
function getsym(sys, sym)
32+
function getsym(sys, sym; inbounds = false)
2933
symtype = symbolic_type(sym)
3034
elsymtype = symbolic_type(eltype(sym))
31-
_getsym(sys, symtype, elsymtype, sym)
35+
getter = _getsym(sys, symtype, elsymtype, sym)
36+
if inbounds
37+
getter = InboundsWrapper(getter)
38+
end
39+
return getter
3240
end
3341

3442
struct GetStateIndex{I} <: AbstractStateGetIndexer
@@ -322,11 +330,19 @@ collection be a mutable reference to the state vector in the value provider. Alt
322330
if this is not possible or additional actions need to be performed when updating state,
323331
[`set_state!`](@ref) can be defined. This function does not work on types for which
324332
[`is_timeseries`](@ref) is [`Timeseries`](@ref).
333+
334+
# Keyword Arguments
335+
336+
- `inbounds`: Whether to wrap the returned function in an `@inbounds`.
325337
"""
326-
function setsym(sys, sym)
338+
function setsym(sys, sym; inbounds = false)
327339
symtype = symbolic_type(sym)
328340
elsymtype = symbolic_type(eltype(sym))
329-
_setsym(sys, symtype, elsymtype, sym)
341+
setter = _setsym(sys, symtype, elsymtype, sym)
342+
if inbounds
343+
setter = InboundsWrapper(setter)
344+
end
345+
return setter
330346
end
331347

332348
struct SetStateIndex{I} <: AbstractSetIndexer
@@ -390,11 +406,19 @@ array/tuple of the aforementioned. All entries `s` in `sym` must satisfy `is_var
390406
or `is_parameter(indp, s)`.
391407
392408
Requires that the value provider implement `state_values`, `parameter_values` and `remake_buffer`.
409+
410+
# Keyword Arguments
411+
412+
- `inbounds`: Whether to wrap the returned function in `@inbounds`.
393413
"""
394-
function setsym_oop(indp, sym)
414+
function setsym_oop(indp, sym; inbounds = false)
395415
symtype = symbolic_type(sym)
396416
elsymtype = symbolic_type(eltype(sym))
397-
return _setsym_oop(indp, symtype, elsymtype, sym)
417+
setter = _setsym_oop(indp, symtype, elsymtype, sym)
418+
if inbounds
419+
setter = InboundsWrapper(setter)
420+
end
421+
return setter
398422
end
399423

400424
struct FullSetter{S, P, I, J}

src/value_provider_interface.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,28 @@ function _root_indp(indp)
260260
end
261261
end
262262

263+
"""
264+
struct InboundsWrapper
265+
266+
Utility struct to wrap a callable in `@inbounds`.
267+
"""
268+
struct InboundsWrapper{F}
269+
fn::F
270+
end
271+
272+
is_indexer_timeseries(::Type{InboundsWrapper{F}}) where {F} = is_indexer_timeseries(F)
273+
indexer_timeseries_index(iw::InboundsWrapper) = indexer_timeseries_index(iw.fn)
274+
as_timeseries_indexer(iw::InboundsWrapper) = InboundsWrapper(as_timeseries_indexer(iw.fn))
275+
function as_not_timeseries_indexer(iw::InboundsWrapper)
276+
InboundsWrapper(as_not_timeseries_indexer(iw.fn))
277+
end
278+
279+
function (ig::InboundsWrapper)(args...)
280+
return @inbounds begin
281+
ig.fn(args...)
282+
end
283+
end
284+
263285
###########
264286
# Errors
265287
###########

0 commit comments

Comments
 (0)