@@ -24,6 +24,12 @@ Base.@propagate_inbounds function pack_scalar_constants!(
2424 return idx + 1
2525end
2626
27+ # Fallback so callers (and static analysis tools like JET) don't see a MethodError.
28+ # Types that want to participate in the ValueInterface must implement a more specific method.
29+ function pack_scalar_constants! (:: AbstractVector{<:Number} , :: Int64 , value)
30+ throw (ArgumentError (" pack_scalar_constants! not implemented for $(typeof (value)) " ))
31+ end
32+
2733"""
2834 unpack_scalar_constants(nvals, idx, value)
2935
@@ -37,10 +43,14 @@ Returns a tuple of the next index to read from, and the filled-in value.
3743"""
3844Base. @propagate_inbounds function unpack_scalar_constants (
3945 nvals:: AbstractVector{<:Number} , idx:: Int64 , value:: T
40- ) where {T}
46+ ) where {T<: Number }
4147 return (idx + 1 , convert (T, nvals[idx]))
4248end
4349
50+ function unpack_scalar_constants (:: AbstractVector{<:Number} , :: Int64 , value)
51+ throw (ArgumentError (" unpack_scalar_constants not implemented for $(typeof (value)) " ))
52+ end
53+
4454"""
4555 count_scalar_constants(value)
4656
6070function _check_is_valid_array (x)
6171 return is_valid_array ([x]) isa Bool && is_valid_array ([x]) == is_valid (x)
6272end
63- function _check_get_number_type (x)
73+ function _check_get_number_type (x:: X ) where {X}
6474 try
65- get_number_type (typeof (x) ) <: Number
75+ get_number_type (X ) <: Number
6676 catch e
6777 @error e
6878 return false
6979 end
7080end
71- function _check_pack_scalar_constants! (x)
72- packed_x = Vector {get_number_type(typeof(x))} (undef, count_scalar_constants (x))
81+ function _check_pack_scalar_constants! (x:: X ) where {X}
82+ if ! applicable (count_scalar_constants, x)
83+ return false
84+ end
85+ n = count_scalar_constants (x)
86+
87+ packed_x = if X <: Number
88+ Vector {X} (undef, n)
89+ else
90+ # For non-`Number` values, we can't assume a concrete scalar type here.
91+ # Use a generic numeric buffer; correctness is checked by roundtripping.
92+ Vector {Float64} (undef, n)
93+ end
94+
95+ if ! applicable (pack_scalar_constants!, packed_x, 1 , x)
96+ return false
97+ end
98+
7399 new_idx = pack_scalar_constants! (packed_x, 1 , x)
74- return new_idx == 1 + count_scalar_constants (x)
100+ return new_idx == 1 + n
75101end
76- function _check_unpack_scalar_constants (x)
77- packed_x = Vector {get_number_type(typeof(x))} (undef, count_scalar_constants (x))
102+ function _check_unpack_scalar_constants (x:: X ) where {X}
103+ if ! applicable (count_scalar_constants, x)
104+ return false
105+ end
106+ n = count_scalar_constants (x)
107+
108+ packed_x = if X <: Number
109+ Vector {X} (undef, n)
110+ else
111+ Vector {Float64} (undef, n)
112+ end
113+
114+ if ! applicable (pack_scalar_constants!, packed_x, 1 , x)
115+ return false
116+ end
117+ if ! applicable (unpack_scalar_constants, packed_x, 1 , x)
118+ return false
119+ end
120+
78121 pack_scalar_constants! (packed_x, 1 , x)
79122 new_idx, x2 = unpack_scalar_constants (packed_x, 1 , x)
80- return new_idx == 1 + count_scalar_constants (x) && x2 == x
123+ return new_idx == 1 + n && x2 == x
81124end
82125function _check_count_scalar_constants (x)
83126 return count_scalar_constants (x) isa Int &&
0 commit comments