Function subtle::conditional_select [] [src]

pub fn conditional_select<T>(a: T, b: T, choice: T) -> T where
    T: PartialEq + PartialOrd + Copy + One + Signed + Sub<T, Output = T> + Not<Output = T> + BitAnd<T, Output = T> + BitOr<T, Output = T>, 

Select a if choice == 1 or select b if choice == 0, in constant time.

Inputs

  • a, b, and choice must be types for which bitwise-AND, and bitwise-OR, bitwise-complement, subtraction, multiplicative identity, copying, partial equality, and partial order comparison are defined.
  • choice: If choice is equal to the multiplicative identity of the type (i.e. 1u8 for u8, etc.), then a is returned. If choice is equal to the additive identity (i.e. 0u8 for u8, etc.) then b is returned.

Warning

The behaviour of this function is undefined if choice is something other than a multiplicative identity or additive identity (i.e. 1u8 or 0u8).

If you somehow manage to design a type which is not a signed integer, and yet implements all the requisite trait bounds for this generic, it's your problem if something breaks.

Examples

This function should work for signed integer types:

let a: i32 = 5;
let b: i32 = 13;

assert!(conditional_select(a, b, 0) == 13);
assert!(conditional_select(a, b, 1) == 5);

let c: i64 = 2343249123;
let d: i64 = 8723884895;

assert!(conditional_select(c, d, 0) == d);
assert!(conditional_select(c, d, 1) == c);

It does not work with i128s, however, because the num crate doesn't implement num::traits::Signed for i128.

TODO

Once #[feature(specialization)] is finished, we should rewrite this. Or find some other way to only implement it for types which we know work correctly.