diff --git a/src/helper_functions.jl b/src/helper_functions.jl index b21cf88e27..6c018bd42c 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -1,7 +1,8 @@ import Base.<= export sign_cadlag, - jump2pi + jump2pi, + check_method_implementation """ sign_cadlag(x::N)::N where {N<:Real} @@ -86,3 +87,68 @@ direction (1, 0). function <=(u::AbstractVector{Float64}, v::AbstractVector{Float64})::Bool return jump2pi(atan2(u[2], u[1])) <= jump2pi(atan2(v[2], v[1])) end + +""" + check_method_implementation(interface::Type, + func_name, + args_funcs::AbstractVector{Function}, + [print_results]::Bool=false + )::Bool + +Check that a given (interface) function is implemented by all subtypes. + +### Input + +- `interface` -- parent interface type +- `func_name` -- function name +- `args_funcs` -- list of functions that each map a type to an argument + signature tuple +- `print_results` -- (optional, default: `false`) flag for printing intermediate + results + +### Output + +`true` iff all subtypes implement the given function. + +### Notes + +It is sufficient that a subinterface implements the function, i.e., it is not +required that every *concrete* type implements the function. + +This function can also print all intermediate results to STDOUT. + +### Examples + +```julia +check_method_implementation(LazySet, σ, + Function[S -> (AbstractVector{Float64}, S)]) +true +``` +""" +function check_method_implementation(interface::Type, + func_name, + args_funcs::AbstractVector{Function}; + print_results::Bool=false + )::Bool + for subtype in subtypes(interface) + found = false + for args_func in args_funcs + if method_exists(func_name, args_func(subtype)) + if print_results + println("found implementation of $func_name for $subtype") + end + found = true + break + end + end + if !found && !check_method_implementation(subtype, func_name, + args_funcs, + print_results=print_results) + if print_results + println("no implementation of $func_name for $subtype") + end + return false + end + end + return true +end