simd_option.rs - source
Description: Source of the Rust file `/Users/erlendbasso/.cargo/registry/src/github.com-1ecc6299db9ec823/simba-0.8.0/src/simd/simd_option.rs`.
Keywords: rust, rustlang, rust-lang

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81

    use crate::simd::{SimdBool, SimdValue};

    //pub trait SimdOption {
    //    type SimdValue: SimdValue;
    //
    //    fn simd_unwrap(self) -> Self::SimdValue;
    //    fn simd_unwrap_or(self, other: impl FnOnce() -> Self::SimdValue) -> Self::SimdValue;
    //}

    //impl<T: SimdValue> SimdOption for Option<T> {
    //    type SimdValue = T;
    //
    //    #[inline(always)]
    //    fn simd_unwrap(self) -> T {
    //        self.unwrap()
    //    }
    //
    //    #[inline(always)]
    //    fn simd_unwrap_or(self, other: impl FnOnce() -> Self::SimdValue) -> Self::SimdValue {
    //        self.unwrap_or_else(other)
    //    }
    //}

    /// Generalization of Option for SIMD computation.
    pub struct SimdOption<V: SimdValue> {
        val: V,
        mask: V::SimdBool,
    }

    impl<V: SimdValue> SimdOption<V> {
        /// Creates a new SIMD option by combining a value and a mask indicating what lane of the value is valid.
        pub fn new(val: V, mask: V::SimdBool) -> Self {
            SimdOption { val, mask }
        }

        /// Return the underlying SIMD boolean mask.
        pub fn mask(&self) -> V::SimdBool {
            self.mask
        }

        /// Return the underlying unfiltered value.
        pub fn value(&self) -> &V {
            &self.val
        }

        /// Converts this SIMD option to a strandard Option.
        ///
        /// If all the bits of `self.mask` are 1, then this returns `Some(self.value())`.
        /// If any bit of `self.mask` is 0, then this returns `None`.
        pub fn option(self) -> Option<V> {
            if self.mask.all() {
                Some(self.val)
            } else {
                None
            }
        }

        /// Retrieve the underlying value if all the bits of `self.mask` are 1.
        ///
        /// Panics if any of the bits of `self.mask` is 0.
        #[inline]
        pub fn simd_unwrap(self) -> V {
            assert!(
                self.mask.all(),
                "Attempt to unwrap an SIMD value with at least one false lane."
            );
            self.val
        }

        /// Merges the value of `self` with the value of `other`.
        ///
        /// Each lane of the result with a corresponding bit mask set to 1 will be filled with the corresponding lanes of `self.value()`.
        /// The lanes of the result with a corresponding bit mask set to 0 will be filled with the corresponding lanes of `other()`.
        ///
        /// The function in `other` should not do any side-effect. Indeed, implementors of this trait are free to decide in what
        /// cases `other` is called or not.
        #[inline(always)]
        pub fn simd_unwrap_or(self, other: impl FnOnce() -> V) -> V {
            self.val.select(self.mask, other())
        }
    }