1 //! Allocator-flexible data types 2 3 // When std is enabled, prefer those types 4 #[cfg(feature = "std")] 5 pub(crate) use self::std::*; 6 7 // When alloc but not std is enabled, use those types 8 #[cfg(all(feature = "alloc", not(feature = "std")))] 9 pub(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")))] 13 pub(crate) use self::core::*; 14 15 /// For when `std` is enabled 16 #[cfg(feature = "std")] 17 mod 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] new_vec_with_capacity<A>(capacity: usize) -> Vec<A>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)] round(value: f32) -> f3235 pub(crate) fn round(value: f32) -> f32 { 36 value.round() 37 } 38 39 /// Rounds up to the nearest whole number 40 #[must_use] 41 #[inline(always)] ceil(value: f32) -> f3242 pub(crate) fn ceil(value: f32) -> f32 { 43 value.ceil() 44 } 45 46 /// Rounds down to the nearest whole number 47 #[must_use] 48 #[inline(always)] floor(value: f32) -> f3249 pub(crate) fn floor(value: f32) -> f32 { 50 value.floor() 51 } 52 53 /// Computes the absolute value 54 #[must_use] 55 #[inline(always)] abs(value: f32) -> f3256 pub(crate) fn abs(value: f32) -> f32 { 57 value.abs() 58 } 59 60 /// Returns the largest of two f32 values 61 #[inline(always)] f32_max(a: f32, b: f32) -> f3262 pub(crate) fn f32_max(a: f32, b: f32) -> f32 { 63 a.max(b) 64 } 65 66 /// Returns the smallest of two f32 values 67 #[inline(always)] f32_min(a: f32, b: f32) -> f3268 pub(crate) fn f32_min(a: f32, b: f32) -> f32 { 69 a.min(b) 70 } 71 } 72 73 /// For when `alloc` but not `std` is enabled 74 #[cfg(all(feature = "alloc", not(feature = "std")))] 75 mod alloc { 76 extern crate alloc; 77 use core::cmp::Ordering; 78 79 /// An allocation-backend agnostic vector type 80 pub(crate) type Vec<A> = alloc::vec::Vec<A>; 81 /// A vector of child nodes 82 pub(crate) type ChildrenVec<A> = alloc::vec::Vec<A>; 83 #[cfg(feature = "grid")] 84 /// A vector of grid tracks 85 pub(crate) type GridTrackVec<A> = alloc::vec::Vec<A>; 86 87 /// Creates a new vector with the capacity for the specified number of items before it must be resized 88 #[must_use] new_vec_with_capacity<A>(capacity: usize) -> Vec<A>89 pub(crate) fn new_vec_with_capacity<A>(capacity: usize) -> Vec<A> { 90 Vec::with_capacity(capacity) 91 } 92 93 /// Rounds to the nearest whole number 94 pub(crate) use super::polyfill::round; 95 96 /// Rounds up to the nearest whole number 97 pub(crate) use super::polyfill::ceil; 98 99 /// Rounds down to the nearest whole number 100 pub(crate) use super::polyfill::floor; 101 102 /// Computes the absolute value 103 pub(crate) use super::polyfill::abs; 104 105 /// Returns the largest of two f32 values 106 #[inline(always)] f32_max(a: f32, b: f32) -> f32107 pub(crate) fn f32_max(a: f32, b: f32) -> f32 { 108 a.max(b) 109 } 110 111 /// Returns the smallest of two f32 values 112 #[inline(always)] f32_min(a: f32, b: f32) -> f32113 pub(crate) fn f32_min(a: f32, b: f32) -> f32 { 114 a.min(b) 115 } 116 } 117 118 /// For when neither `alloc` nor `std` is enabled 119 #[cfg(all(not(feature = "alloc"), not(feature = "std")))] 120 mod core { 121 use core::cmp::Ordering; 122 123 /// The maximum number of nodes in the tree 124 pub const MAX_NODE_COUNT: usize = 256; 125 /// The maximum number of children of any given node 126 pub const MAX_CHILD_COUNT: usize = 16; 127 #[cfg(feature = "grid")] 128 /// The maximum number of children of any given node 129 pub const MAX_GRID_TRACKS: usize = 16; 130 131 /// An allocation-backend agnostic vector type 132 pub(crate) type Vec<A> = arrayvec::ArrayVec<A, MAX_NODE_COUNT>; 133 /// A vector of child nodes, whose length cannot exceed [`MAX_CHILD_COUNT`] 134 pub(crate) type ChildrenVec<A> = arrayvec::ArrayVec<A, MAX_CHILD_COUNT>; 135 #[cfg(feature = "grid")] 136 /// A vector of grid tracks 137 pub(crate) type GridTrackVec<A> = arrayvec::ArrayVec<A, MAX_GRID_TRACKS>; 138 139 /// Creates a new map with the capacity for the specified number of items before it must be resized 140 /// 141 /// This vector cannot be resized. 142 #[must_use] new_vec_with_capacity<A, const CAP: usize>(_capacity: usize) -> arrayvec::ArrayVec<A, CAP>143 pub(crate) fn new_vec_with_capacity<A, const CAP: usize>(_capacity: usize) -> arrayvec::ArrayVec<A, CAP> { 144 arrayvec::ArrayVec::new() 145 } 146 147 /// Rounds to the nearest whole number 148 pub(crate) use super::polyfill::round; 149 150 /// Computes the absolute value 151 pub(crate) use super::polyfill::abs; 152 153 /// Returns the largest of two f32 values 154 #[inline(always)] f32_max(a: f32, b: f32) -> f32155 pub(crate) fn f32_max(a: f32, b: f32) -> f32 { 156 a.max(b) 157 } 158 159 /// Returns the smallest of two f32 values 160 #[inline(always)] f32_min(a: f32, b: f32) -> f32161 pub(crate) fn f32_min(a: f32, b: f32) -> f32 { 162 a.min(b) 163 } 164 } 165 166 /// Implementations of float functions for no_std and alloc builds 167 /// Copied from `num-traits` crate 168 #[cfg(not(feature = "std"))] 169 mod polyfill { 170 #[must_use] 171 #[inline(always)] fract(value: f32) -> f32172 fn fract(value: f32) -> f32 { 173 if value == 0.0 { 174 0.0 175 } else { 176 value % 1.0 177 } 178 } 179 180 #[must_use] 181 #[inline(always)] round(value: f32) -> f32182 pub(crate) fn round(value: f32) -> f32 { 183 let f = fract(value); 184 if f.is_nan() || f == 0.0 { 185 value 186 } else if value > 0.0 { 187 if f < 0.5 { 188 value - f 189 } else { 190 value - f + 1.0 191 } 192 } else if -f < 0.5 { 193 value - f 194 } else { 195 value - f - 1.0 196 } 197 } 198 199 #[must_use] 200 #[inline(always)] floor(value: f32) -> f32201 pub(crate) fn floor(value: f32) -> f32 { 202 let f = fract(value); 203 if f.is_nan() || f == 0.0 { 204 value 205 } else if value < 0.0 { 206 value - f - 1.0 207 } else { 208 value - f 209 } 210 } 211 212 #[must_use] 213 #[inline(always)] ceil(value: f32) -> f32214 pub(crate) fn ceil(value: f32) -> f32 { 215 let f = fract(value); 216 if f.is_nan() || f == 0.0 { 217 value 218 } else if value > 0.0 { 219 value - f + 1.0 220 } else { 221 value - f 222 } 223 } 224 225 /// Computes the absolute value 226 #[must_use] 227 #[inline(always)] abs(value: f32) -> f32228 pub(crate) fn abs(value: f32) -> f32 { 229 if value.is_sign_positive() { 230 return value; 231 } else if value.is_sign_negative() { 232 return -value; 233 } else { 234 f32::NAN 235 } 236 } 237 } 238