Fully remove num-traits (#762)
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 /// Rounds up to the nearest whole number
40 #[must_use]
41 #[inline(always)]
42 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)]
49 pub(crate) fn floor(value: f32) -> f32 {
50 value.floor()
51 }
52
53 /// Computes the absolute value
54 #[must_use]
55 #[inline(always)]
56 pub(crate) fn abs(value: f32) -> f32 {
57 value.abs()
58 }
59
60 /// Returns the largest of two f32 values
61 #[inline(always)]
62 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)]
68 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")))]
75mod 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]
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)]
107 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)]
113 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")))]
120mod 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]
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)]
155 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)]
161 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"))]
169mod polyfill {
170 #[must_use]
171 #[inline(always)]
172 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)]
182 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)]
201 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)]
214 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)]
228 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}