gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5364Rust 86Markdown 12TOML 91841 Definitions

⎇ 016b93a3d88e9620860b0c1c61de603e39142d14 src/util/sys.rs Rust · 192 lines · 5.4 KB History Who touched what raw

Eliminate the num-traits dependency (#761) 016b93a3d · Nico Burns ·

1//! Allocator-flexible data types
2
3// When std is enabled, prefer those types
4#[cfg(feature = "std")]
5pub(crate) use self::std::*;
6
7// When alloc but not std is enabled, use those types
8#[cfg(all(feature = "alloc", not(feature = "std")))]
9pub(crate) use self::alloc::*;
10
11// When neither alloc or std is enabled, use a heapless fallback
12#[cfg(all(not(feature = "alloc"), not(feature = "std")))]
13pub(crate) use self::core::*;
14
15/// For when `std` is enabled
16#[cfg(feature = "std")]
17mod std {
18    /// An allocation-backend agnostic vector type
19    pub(crate) type Vec<A> = std::vec::Vec<A>;
20    /// A vector of child nodes
21    pub(crate) type ChildrenVec<A> = std::vec::Vec<A>;
22    #[cfg(feature = "grid")]
23    /// A vector of grid tracks
24    pub(crate) type GridTrackVec<A> = std::vec::Vec<A>;
25
26    /// Creates a new vector with the capacity for the specified number of items before it must be resized
27    #[must_use]
28    pub(crate) fn new_vec_with_capacity<A>(capacity: usize) -> Vec<A> {
29        Vec::with_capacity(capacity)
30    }
31
32    /// Rounds to the nearest whole number
33    #[must_use]
34    #[inline(always)]
35    pub(crate) fn round(value: f32) -> f32 {
36        value.round()
37    }
38
39    /// Computes the absolute value
40    #[must_use]
41    #[inline(always)]
42    pub(crate) fn abs(value: f32) -> f32 {
43        value.abs()
44    }
45
46    /// Returns the largest of two f32 values
47    #[inline(always)]
48    pub(crate) fn f32_max(a: f32, b: f32) -> f32 {
49        a.max(b)
50    }
51
52    /// Returns the smallest of two f32 values
53    #[inline(always)]
54    pub(crate) fn f32_min(a: f32, b: f32) -> f32 {
55        a.min(b)
56    }
57}
58
59/// For when `alloc` but not `std` is enabled
60#[cfg(all(feature = "alloc", not(feature = "std")))]
61mod alloc {
62    extern crate alloc;
63    use core::cmp::Ordering;
64
65    /// An allocation-backend agnostic vector type
66    pub(crate) type Vec<A> = alloc::vec::Vec<A>;
67    /// A vector of child nodes
68    pub(crate) type ChildrenVec<A> = alloc::vec::Vec<A>;
69    #[cfg(feature = "grid")]
70    /// A vector of grid tracks
71    pub(crate) type GridTrackVec<A> = alloc::vec::Vec<A>;
72
73    /// Creates a new vector with the capacity for the specified number of items before it must be resized
74    #[must_use]
75    pub(crate) fn new_vec_with_capacity<A>(capacity: usize) -> Vec<A> {
76        Vec::with_capacity(capacity)
77    }
78
79    /// Rounds to the nearest whole number
80    pub(crate) use super::polyfill::round;
81
82    /// Computes the absolute value
83    pub(crate) use super::polyfill::abs;
84
85    /// Returns the largest of two f32 values
86    #[inline(always)]
87    pub(crate) fn f32_max(a: f32, b: f32) -> f32 {
88        a.max(b)
89    }
90
91    /// Returns the smallest of two f32 values
92    #[inline(always)]
93    pub(crate) fn f32_min(a: f32, b: f32) -> f32 {
94        a.min(b)
95    }
96}
97
98/// For when neither `alloc` nor `std` is enabled
99#[cfg(all(not(feature = "alloc"), not(feature = "std")))]
100mod core {
101    use core::cmp::Ordering;
102
103    /// The maximum number of nodes in the tree
104    pub const MAX_NODE_COUNT: usize = 256;
105    /// The maximum number of children of any given node
106    pub const MAX_CHILD_COUNT: usize = 16;
107    #[cfg(feature = "grid")]
108    /// The maximum number of children of any given node
109    pub const MAX_GRID_TRACKS: usize = 16;
110
111    /// An allocation-backend agnostic vector type
112    pub(crate) type Vec<A> = arrayvec::ArrayVec<A, MAX_NODE_COUNT>;
113    /// A vector of child nodes, whose length cannot exceed [`MAX_CHILD_COUNT`]
114    pub(crate) type ChildrenVec<A> = arrayvec::ArrayVec<A, MAX_CHILD_COUNT>;
115    #[cfg(feature = "grid")]
116    /// A vector of grid tracks
117    pub(crate) type GridTrackVec<A> = arrayvec::ArrayVec<A, MAX_GRID_TRACKS>;
118
119    /// Creates a new map with the capacity for the specified number of items before it must be resized
120    ///
121    /// This vector cannot be resized.
122    #[must_use]
123    pub(crate) fn new_vec_with_capacity<A, const CAP: usize>(_capacity: usize) -> arrayvec::ArrayVec<A, CAP> {
124        arrayvec::ArrayVec::new()
125    }
126
127    /// Rounds to the nearest whole number
128    pub(crate) use super::polyfill::round;
129
130    /// Computes the absolute value
131    pub(crate) use super::polyfill::abs;
132
133    /// Returns the largest of two f32 values
134    #[inline(always)]
135    pub(crate) fn f32_max(a: f32, b: f32) -> f32 {
136        a.max(b)
137    }
138
139    /// Returns the smallest of two f32 values
140    #[inline(always)]
141    pub(crate) fn f32_min(a: f32, b: f32) -> f32 {
142        a.min(b)
143    }
144}
145
146/// Implementations of float functions for no_std and alloc builds
147/// Copied from `num-traits` crate
148mod polyfill {
149    #[inline(always)]
150    #[cfg(not(feature = "std"))]
151    fn fract(value: f32) -> f32 {
152        if value == 0.0 {
153            0.0
154        } else {
155            value % 1.0
156        }
157    }
158
159    #[must_use]
160    #[inline(always)]
161    #[cfg(not(feature = "std"))]
162    pub(crate) fn round(value: f32) -> f32 {
163        let f = fract(value);
164        if f.is_nan() || f == 0.0 {
165            value
166        } else if value > 0.0 {
167            if f < 0.5 {
168                value - f
169            } else {
170                value - f + 1.0
171            }
172        } else if -f < 0.5 {
173            value - f
174        } else {
175            value - f - 1.0
176        }
177    }
178
179    /// Computes the absolute value
180    #[must_use]
181    #[inline(always)]
182    #[cfg(not(feature = "std"))]
183    pub(crate) fn abs(value: f32) -> f32 {
184        if value.is_sign_positive() {
185            return value;
186        } else if value.is_sign_negative() {
187            return -value;
188        } else {
189            f32::NAN
190        }
191    }
192}