1#[doc(hidden)]
2#[macro_export]
3macro_rules! __declare_string_cmp_fns {
4 (
5 import_path = $path:expr,
6
7 equality_fn = $eq_str:ident,
8 ordering_fn = $cmp_str:ident,
9 ordering_fn_inner = $cmp_str_inner:ident,
11 ) => {
12 $crate::__declare_string_cmp_fns! {
13 @inner
14 equality_fn = $eq_str,
15 ordering_fn = $cmp_str,
16 use_eq_str = concat!("use ", $path, "::", stringify!($eq_str), ";"),
17 use_cmp_str = concat!("use ", $path, "::", stringify!($cmp_str), ";"),
18 }
19 };
20 (@inner
21
22 equality_fn = $eq_str:ident,
23 ordering_fn = $cmp_str:ident,
24 use_eq_str = $eq_str_import:expr,
25 use_cmp_str = $cmp_str_import:expr,
26 ) => {
27 $crate::__delegate_const_eq! {
28 skip_coerce;
29 #[doc = $eq_str_import]
35 #[inline]
53 pub const fn eq_str(ref left: &str, right: &str) -> bool {
54 let left = left.as_bytes();
55 let right = right.as_bytes();
56
57 if left.len() != right.len() {
58 return false;
59 }
60
61 let mut i = 0;
62 while i != left.len() {
63 if left[i] != right[i] {
64 return false;
65 }
66 i += 1;
67 }
68
69 true
70 }
71 }
72
73 __delegate_const_ord! {
74 skip_coerce;
75 #[doc = $cmp_str_import]
81 #[inline]
101 pub const fn cmp_str(ref left: &str, right: &str) -> $crate::__::Ordering {
102 cmp_str_inner(left.as_bytes(), right.as_bytes()).to_ordering()
103 }
104 }
105
106 #[inline]
107 const fn cmp_str_inner(left: &[u8], right: &[u8]) -> $crate::__::U8Ordering {
108 use $crate::__::U8Ordering;
109
110 let left_len = left.len();
111 let right_len = right.len();
112 let (min_len, on_ne) = if left_len < right_len {
113 (left_len, U8Ordering::LESS)
114 } else {
115 (right_len, U8Ordering::GREATER)
116 };
117
118 let mut i = 0;
119 while i < min_len {
120 $crate::__priv_ret_if_ne! {left[i], right[i]}
121 i += 1;
122 }
123
124 if left_len == right_len {
125 U8Ordering::EQUAL
126 } else {
127 on_ne
128 }
129 }
130 };
131}
132
133#[doc(hidden)]
134#[macro_export]
135macro_rules! __declare_slice_cmp_fns{
136 (
137 import_path = $path:expr,
138
139
140 $((
141 $(#[$attr_both:meta])*,
142 $(#[$attr_eq:meta])*,
143 $(#[$attr_ord:meta])*,
144 $type:ty,
145 $eq_fn_name:ident,
146 $cmp_fn_name:ident,
147 ))*
148 )=>{
149 $(
150 __declare_slice_cmp_fns!{
151 @step_two
152 import_path = $path,
153
154 $(#[$attr_both])*,
155 $(#[$attr_eq])*,
156 $(#[$attr_ord])*,
157 concat!(
158 "Compares two `&[",
159 stringify!($type),
160 "]` for equality.",
161 ),
162 concat!(
163 "Compares two `&[",
164 stringify!($type),
165 "]`, returning the order of `left` relative to `right`.",
166 ),
167 $type,
168 $eq_fn_name,
169 $cmp_fn_name,
170 }
171 )*
172 };
173 (@step_two
174 import_path = $path:expr,
175
176 $(#[$attr_both:meta])*,
177 $(#[$attr_eq:meta])*,
178 $(#[$attr_ord:meta])*,
179 $docs_eq:expr,
180 $docs_ord:expr,
181 $ty:ty,
182 $eq_fn_name:ident,
183 $cmp_fn_name:ident,
184 ) => {
185 $crate::__delegate_const_eq!{
186 skip_coerce;
187
188 #[doc = $docs_eq]
189 $(#[$attr_both])*
190 $(#[$attr_eq])*
191 #[inline]
192 pub const fn $eq_fn_name(ref left: &[$ty], right: &[$ty]) -> bool {
193 if left.len() != right.len() {
194 return false;
195 }
196
197 let mut i = 0;
198 while i != left.len() {
199 if left[i] != right[i] {
200 return false;
201 }
202 i += 1;
203 }
204
205 true
206 }
207 }
208
209
210
211 __delegate_const_ord!{
212 skip_coerce;
213 for['a,]
214
215 #[doc = $docs_ord]
216 $(#[$attr_both])*
217 $(#[$attr_ord])*
218 #[inline]
219 pub const fn $cmp_fn_name(ref left: &[$ty], right: &[$ty]) -> $crate::__::Ordering {
220 use $crate::__::U8Ordering;
221
222 const fn cmp_inner(left: &[$ty], right: &[$ty]) -> $crate::__::U8Ordering {
223 let left_len = left.len();
224
225 $crate::__priv_ret_if_ne! {left_len, right.len()}
226
227 let mut i = 0;
228 while i < left_len {
229 $crate::__priv_ret_if_ne! {left[i], right[i]}
230 i += 1;
231 }
232
233 U8Ordering::EQUAL
234 }
235
236 cmp_inner(left, right).to_ordering()
237 }
238 }
239
240 };
241}
242
243#[doc(hidden)]
244#[macro_export]
245macro_rules! __declare_fns_with_docs{
246 (
247 $(($($args:tt)*))*
248
249 docs $docs:tt
250
251 macro = $macro:ident ! $macro_prefix:tt,
252 )=>{
253 $(
254 $crate::__declare_fns_with_docs!{
255 @inner
256 ($($args)*)
257
258 docs $docs
259
260 macro = $macro ! $macro_prefix,
261 }
262 )*
263 };
264 (@inner
265 (
266 $type:ty,
267 ($($func_name:ident),* $(,)?)
268 $($rem:tt)*
269 )
270
271 docs(
272 $(($before:expr, $after:expr))*
273 )
274
275 macro = $macro:ident ! ($($prefix:tt)*),
276 ) => {
277
278 $macro!{
279 $($prefix)*
280 ($type, ($($func_name),*) $($rem)* )
281
282 docs(
283 $(concat!($before, stringify!($type), $after)),*
284 )
285 }
286
287
288 };
289 (@inner
290 (
291 $type:ty,
292 ($($func_name:ident),* $(,)?)
293 $($rem:tt)*
294 )
295
296 docs(default)
297
298 macro = $macro:ident ! ($($prefix:tt)*),
299 ) => {
300
301 $macro!{
302 $($prefix)*
303 ($type, ($($func_name),*) $($rem)* )
304
305 docs(
306 concat!(
307 "Compares two `",
308 stringify!($type),
309 "` for equality.",
310 ),
311 concat!(
312 "Compares two `",
313 stringify!($type),
314 "`, returning the ordering of `left` relative to `right`."
315 ),
316 )
317 }
318
319
320 };
321}
322
323macro_rules! __impl_option_cmp_fns {
324 (
325 $(#[$attr:meta])*
326 $(for[$($impl:tt)*])?
327 params($l:ident, $r:ident)
328 eq_comparison = $eq_comparison:expr,
329 cmp_comparison = $cmp_comparison:expr,
330 parameter_copyability = $copyab:ident,
331
332 ($type:ty, ($eq_fn_name:ident, $cmp_fn_name:ident))
333
334 docs( $docs_eq:expr, $docs_cmp:expr, )
335 ) => (
336 __delegate_const_eq!{
337 $(for[$($impl)*])?
338
339 #[doc = $docs_eq]
340 $(#[$attr])*
341 pub const fn $eq_fn_name($copyab left: $type, right: $type) -> bool {
342 match (left, right) {
343 (Some($l), Some($r)) => $eq_comparison,
344 (None, None) => true,
345 _ => false,
346 }
347 }
348 }
349
350 __delegate_const_ord!{
351 $(for[$($impl)*])?
352
353 #[doc = $docs_cmp]
354 $(#[$attr])*
355 pub const fn $cmp_fn_name($copyab left: $type, right: $type) -> core::cmp::Ordering {
356 use core::cmp::Ordering;
357
358 match (left, right) {
359 (Some($l), Some($r)) => $cmp_comparison,
360 (Some(_), None) => Ordering::Greater,
361 (None, Some(_)) => Ordering::Less,
362 (None, None) => Ordering::Equal,
363 }
364 }
365 }
366 )
367}