diff --git a/Project.toml b/Project.toml index 89edd3b4..a40f986c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DynamicExpressions" uuid = "a40a106e-89c9-4ca8-8020-a735e8728b6b" authors = ["MilesCranmer "] -version = "1.9.1" +version = "1.9.2" [deps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" diff --git a/src/Evaluate.jl b/src/Evaluate.jl index cf2ee2e0..a03d0140 100644 --- a/src/Evaluate.jl +++ b/src/Evaluate.jl @@ -36,6 +36,10 @@ struct ArrayBuffer{A<:AbstractMatrix,R<:Base.RefValue{<:Integer}} index::R end +function Base.copy(buffer::ArrayBuffer) + return ArrayBuffer(copy(buffer.array), Ref(buffer.index[])) +end + reset_index!(buffer::ArrayBuffer) = buffer.index[] = 0 reset_index!(::Nothing) = nothing @@ -117,6 +121,17 @@ end @unstable @inline _to_bool_val(x::Bool) = x ? Val(true) : Val(false) @inline _to_bool_val(::Val{T}) where {T} = Val(T::Bool) +_copy(x) = copy(x) +_copy(::Nothing) = nothing +function Base.copy(eval_options::EvalOptions) + return EvalOptions(; + turbo=eval_options.turbo, + bumper=eval_options.bumper, + early_exit=eval_options.early_exit, + buffer=_copy(eval_options.buffer), + ) +end + @unstable function _process_deprecated_kws(eval_options, deprecated_kws) turbo = get(deprecated_kws, :turbo, nothing) bumper = get(deprecated_kws, :bumper, nothing) diff --git a/test/test_evaluation.jl b/test/test_evaluation.jl index bb0dcc51..f744bdf5 100644 --- a/test/test_evaluation.jl +++ b/test/test_evaluation.jl @@ -288,6 +288,36 @@ end @test_throws ArgumentError ex(randn(1, 5), OperatorEnum(); bad_arg=1) end +@testitem "Test EvalOptions copy" begin + using DynamicExpressions + using DynamicExpressions: ArrayBuffer + + # Test copying with various configurations + buffer = zeros(5, 10) + buffer_ref = Ref(0) + original = EvalOptions(; + turbo=true, bumper=false, early_exit=true, buffer=ArrayBuffer(buffer, buffer_ref) + ) + copied = copy(original) + + # Test that all fields are equal + @test copied.turbo == original.turbo + @test copied.bumper == original.bumper + @test copied.early_exit == original.early_exit + @test copied.buffer.array == original.buffer.array + @test copied.buffer.index[] == original.buffer.index[] + + # Test that buffer is copied, not referenced + @test copied.buffer !== original.buffer + @test copied.buffer.array !== original.buffer.array + @test copied.buffer.index !== original.buffer.index + + # Test without buffer + original_no_buffer = EvalOptions(; turbo=true, bumper=false, early_exit=true) + copied_no_buffer = copy(original_no_buffer) + @test copied_no_buffer.buffer === nothing +end + @testitem "Test Inf val" begin using DynamicExpressions