• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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