[][src]Macro multiversion::multiversion

multiversion!() { /* proc-macro */ }

Provides function multiversioning by explicitly specifying function versions.

Functions are selected in order, calling the first matching target. The final function must have the default target, which indicates that this function does not require any special features.

Safety

Functions compiled with the target_feature attribute must be marked unsafe, since calling them on an unsupported CPU results in a crash. The multiversion! macro will produce a safe function that calls unsafe function versions, and the safety contract is fulfilled as long as your specified targets are correct. If your function versions are unsafe for any other reason, you must remember to mark your generated function unsafe as well.

Examples

A simple feature-specific function

This example creates a function where_am_i that prints the detected CPU feature.

use multiversion::multiversion;

multiversion!{
    fn where_am_i()
    "[x86|x86_64]+avx" => where_am_i_avx,
    "x86+sse" => where_am_i_sse,
    "[arm|aarch64]+neon" => where_am_i_neon,
    default => where_am_i_generic,
}

fn where_am_i_avx() {
    println!("avx");
}

fn where_am_i_sse() {
    println!("sse");
}

fn where_am_i_neon() {
    println!("neon");
}

fn where_am_i_generic() {
    println!("generic");
}

Making target_feature functions safe

This example is the same as the above example, but calls unsafe specialized functions. Note that the where_am_i function is still safe, since we know we are only calling specialized functions on supported CPUs.

use multiversion::multiversion;

multiversion!{
    fn where_am_i()
    "[x86|x86_64]+avx" => where_am_i_avx,
    "x86+sse" => where_am_i_sse,
    "[arm|aarch64]+neon" => where_am_i_neon,
    default => where_am_i_generic,
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[target_feature(enable = "avx")]
unsafe fn where_am_i_avx() {
    println!("avx");
}

#[cfg(target_arch = "x86")]
#[target_feature(enable = "sse")]
unsafe fn where_am_i_sse() {
    println!("sse");
}

#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
#[target_feature(enable = "neon")]
unsafe fn where_am_i_neon() {
    println!("neon");
}

fn where_am_i_generic() {
    println!("generic");
}