@@ -260,22 +260,45 @@ end
260260# Basically we want to vectorize every single operation on ValidVector,
261261# so that the user can use it easily.
262262
263+ function _apply_operator (op:: F , x:: Vararg{Any,N} ) where {F<: Function ,N}
264+ vx = map (_get_value, x)
265+ safe_op = get_safe_op (op)
266+ result = safe_op .(vx... )
267+ return ValidVector (result, is_valid_array (result))
268+ end
269+
263270function apply_operator (op:: F , x:: Vararg{Any,N} ) where {F<: Function ,N}
264271 if all (_is_valid, x)
265- vx = map (_get_value, x)
266- safe_op = get_safe_op (op)
267- result = safe_op .(vx... )
268- return ValidVector (result, is_valid_array (result))
272+ return _apply_operator (op, x... )
269273 else
270274 example_vector =
271275 something (map (xi -> xi isa ValidVector ? xi : nothing , x)... ):: ValidVector
272- return ValidVector (_get_value (example_vector), false )
276+ expected_return_type = Base. promote_op (
277+ _apply_operator, typeof (op), map (typeof, x)...
278+ )
279+ if expected_return_type != = Union{} &&
280+ expected_return_type <: ValidVector{<:AbstractArray}
281+ return ValidVector (
282+ _match_eltype (expected_return_type, example_vector. x), false
283+ ):: expected_return_type
284+ else
285+ return ValidVector (example_vector. x, false )
286+ end
273287 end
274288end
275289_is_valid (x:: ValidVector ) = x. valid
276290_is_valid (x) = true
277291_get_value (x:: ValidVector ) = x. x
278292_get_value (x) = x
293+ function _match_eltype (
294+ :: Type{<:ValidVector{<:AbstractArray{T1}}} , x:: AbstractArray{T2}
295+ ) where {T1,T2}
296+ if T1 == T2
297+ return x
298+ else
299+ return Base. Fix1 (convert, T1).(x)
300+ end
301+ end
279302
280303struct ValidVectorMixError <: Exception end
281304struct ValidVectorAccessError <: Exception end
0 commit comments