taffy 0.15.0

A flexible UI layout library
Documentation
//! Allocator-flexible data types

// When std is enabled, prefer those types
#[cfg(feature = "std")]
pub(crate) use self::std::*;

// Otherwise, use the types from the alloc crate
#[cfg(not(feature = "std"))]
pub(crate) use self::alloc::*;

/// For when `std` is enabled
#[cfg(feature = "std")]
mod std {
    /// A string
    pub(crate) type String = std::string::String;
    /// The default type for representing strings in Taffy styles
    pub(crate) type DefaultCheapStr = String;
    /// A map
    pub(crate) type Map<K, V> = std::collections::HashMap<K, V, std::collections::hash_map::RandomState>;
    /// An allocation-backend agnostic vector type
    pub(crate) type Vec<A> = std::vec::Vec<A>;
    /// An allocation-backend agnostic boxed pointer type
    pub(crate) type Box<A> = std::boxed::Box<A>;
    /// A vector of child nodes
    pub(crate) type ChildrenVec<A> = std::vec::Vec<A>;
    #[cfg(feature = "grid")]
    /// A vector of grid tracks
    pub(crate) type GridTrackVec<A> = std::vec::Vec<A>;

    /// Creates a new vector with the capacity for the specified number of items before it must be resized
    #[must_use]
    pub(crate) fn new_vec_with_capacity<A>(capacity: usize) -> Vec<A> {
        Vec::with_capacity(capacity)
    }

    /// Creates a new empty `ChildrenVec` in a const context
    #[must_use]
    pub(crate) const fn new_const_children_vec<A>() -> ChildrenVec<A> {
        Vec::new()
    }

    /// Rounds to the nearest whole number
    #[must_use]
    #[inline(always)]
    pub(crate) fn round(value: f32) -> f32 {
        (value + 0.5).floor()
    }

    /// Rounds up to the nearest whole number
    #[must_use]
    #[inline(always)]
    pub(crate) fn ceil(value: f32) -> f32 {
        value.ceil()
    }

    /// Rounds down to the nearest whole number
    #[must_use]
    #[inline(always)]
    pub(crate) fn floor(value: f32) -> f32 {
        value.floor()
    }

    /// Computes the absolute value
    #[must_use]
    #[inline(always)]
    pub(crate) fn abs(value: f32) -> f32 {
        value.abs()
    }

    /// Returns the largest of two f32 values
    #[inline(always)]
    pub(crate) fn f32_max(a: f32, b: f32) -> f32 {
        a.max(b)
    }

    /// Returns the smallest of two f32 values
    #[inline(always)]
    pub(crate) fn f32_min(a: f32, b: f32) -> f32 {
        a.min(b)
    }
}

/// For when `std` is not enabled
#[cfg(not(feature = "std"))]
mod alloc {
    extern crate alloc;

    /// A string
    pub(crate) type String = alloc::string::String;
    /// The default type for representing strings in Taffy styles
    pub(crate) type DefaultCheapStr = String;
    /// A map
    // TODO: consider using hashbrown
    pub(crate) type Map<K, V> = alloc::collections::BTreeMap<K, V>;
    /// An allocation-backend agnostic vector type
    pub(crate) type Vec<A> = alloc::vec::Vec<A>;
    /// An allocation-backend agnostic boxed pointer type
    pub(crate) type Box<A> = alloc::boxed::Box<A>;
    /// A vector of child nodes
    pub(crate) type ChildrenVec<A> = alloc::vec::Vec<A>;
    #[cfg(feature = "grid")]
    /// A vector of grid tracks
    pub(crate) type GridTrackVec<A> = alloc::vec::Vec<A>;

    /// Creates a new vector with the capacity for the specified number of items before it must be resized
    #[must_use]
    pub(crate) fn new_vec_with_capacity<A>(capacity: usize) -> Vec<A> {
        Vec::with_capacity(capacity)
    }

    /// Creates a new empty `ChildrenVec` in a const context
    #[must_use]
    pub(crate) const fn new_const_children_vec<A>() -> ChildrenVec<A> {
        Vec::new()
    }

    /// Rounds to the nearest whole number
    pub(crate) use super::polyfill::round;

    /// Rounds up to the nearest whole number
    pub(crate) use super::polyfill::ceil;

    /// Rounds down to the nearest whole number
    pub(crate) use super::polyfill::floor;

    /// Computes the absolute value
    pub(crate) use super::polyfill::abs;

    /// Returns the largest of two f32 values
    #[inline(always)]
    pub(crate) fn f32_max(a: f32, b: f32) -> f32 {
        a.max(b)
    }

    /// Returns the smallest of two f32 values
    #[inline(always)]
    pub(crate) fn f32_min(a: f32, b: f32) -> f32 {
        a.min(b)
    }
}

/// Implementations of float functions for no_std builds
/// Copied from `num-traits` crate
#[cfg(not(feature = "std"))]
mod polyfill {
    #[must_use]
    #[inline(always)]
    fn fract(value: f32) -> f32 {
        if value == 0.0 {
            0.0
        } else {
            value % 1.0
        }
    }

    #[must_use]
    #[inline(always)]
    pub(crate) fn round(value: f32) -> f32 {
        let f = fract(value);
        if f.is_nan() || f == 0.0 {
            value
        } else if value > 0.0 {
            if f < 0.5 {
                value - f
            } else {
                value - f + 1.0
            }
        } else if -f < 0.5 {
            value - f
        } else {
            value - f - 1.0
        }
    }

    #[must_use]
    #[inline(always)]
    pub(crate) fn floor(value: f32) -> f32 {
        let f = fract(value);
        if f.is_nan() || f == 0.0 {
            value
        } else if value < 0.0 {
            value - f - 1.0
        } else {
            value - f
        }
    }

    #[must_use]
    #[inline(always)]
    pub(crate) fn ceil(value: f32) -> f32 {
        let f = fract(value);
        if f.is_nan() || f == 0.0 {
            value
        } else if value > 0.0 {
            value - f + 1.0
        } else {
            value - f
        }
    }

    /// Computes the absolute value
    #[must_use]
    #[inline(always)]
    pub(crate) fn abs(value: f32) -> f32 {
        if value.is_sign_positive() {
            return value;
        } else if value.is_sign_negative() {
            return -value;
        } else {
            f32::NAN
        }
    }
}