wt_slice/lib.rs
1// Copyright 2017 Alkis Evlogimenos
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![no_std]
16
17//! This crate provides extensions for [`slice`]s.
18//!
19//! # Examples
20//!
21//! ```
22//! use wt_slice::*;
23//!
24//! let b = [1, 3];
25//!
26//! assert_eq!(b.lower_bound(&1), 0);
27//!
28//! assert_eq!(b.upper_bound(&1), 1);
29//!
30//! assert_eq!(b.equal_range(&3), 1..2);
31//! ```
32//!
33//! [`slice`]: https://doc.rust-lang.org/stable/std/primitive.slice.html
34use core::cmp::Ordering::{self, Less, Greater};
35
36/// Exact search for ordered slices with an early equality exit and branchless
37/// search-direction selection.
38///
39/// This combines the useful properties of a conventional early-exit binary
40/// search with the conditional selection used by modern standard-library
41/// binary search implementations. It returns either a matching index or the
42/// position where the value can be inserted while preserving order.
43pub trait ExactSearch {
44 type Item;
45
46 /// Searches for `x`, returning a matching index or its insertion position.
47 fn exact_search(&self, x: &Self::Item) -> Result<usize, usize>
48 where
49 Self::Item: Ord;
50
51 /// Searches with a comparator, returning a match or insertion position.
52 fn exact_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
53 where
54 F: FnMut(&'a Self::Item) -> Ordering;
55
56 /// Searches by an extracted key, returning a match or insertion position.
57 fn exact_search_by_key<'a, K, F>(&'a self, key: &K, f: F) -> Result<usize, usize>
58 where
59 F: FnMut(&'a Self::Item) -> K,
60 K: Ord;
61}
62
63impl<T> ExactSearch for [T] {
64 type Item = T;
65
66 #[inline]
67 fn exact_search(&self, x: &Self::Item) -> Result<usize, usize>
68 where
69 Self::Item: Ord,
70 {
71 self.exact_search_by(|candidate| candidate.cmp(x))
72 }
73
74 #[inline]
75 fn exact_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
76 where
77 F: FnMut(&'a Self::Item) -> Ordering,
78 {
79 let mut size = self.len();
80 if size == 0 {
81 return Err(0);
82 }
83
84 let mut base = 0;
85 while size > 1 {
86 let half = size / 2;
87 let mid = base + half;
88
89 // SAFETY: `base + size` never exceeds `self.len()`, and
90 // `half < size`, so `mid` is always a valid index.
91 let cmp = f(unsafe { self.get_unchecked(mid) });
92 if cmp == Ordering::Equal {
93 return Ok(mid);
94 }
95
96 // Search direction is deliberately expressed as an unpredictable
97 // selection so supported targets use a conditional move rather
98 // than a hard-to-predict left/right branch.
99 base = core::hint::select_unpredictable(cmp == Greater, base, mid);
100 size -= half;
101 }
102
103 // SAFETY: a non-empty search retains `base < self.len()`.
104 match f(unsafe { self.get_unchecked(base) }) {
105 Ordering::Less => Err(base + 1),
106 Ordering::Equal => Ok(base),
107 Ordering::Greater => Err(base),
108 }
109 }
110
111 #[inline]
112 fn exact_search_by_key<'a, K, F>(&'a self, key: &K, mut f: F) -> Result<usize, usize>
113 where
114 F: FnMut(&'a Self::Item) -> K,
115 K: Ord,
116 {
117 self.exact_search_by(|candidate| f(candidate).cmp(key))
118 }
119}
120
121/// Extends [`slice`] with fast operations on ordered slices.
122///
123/// [`slice`]: https://doc.rust-lang.org/stable/std/primitive.slice.html
124pub trait Ext {
125 type Item;
126
127 /// Returns the index `i` pointing to the first element in the ordered slice
128 /// that is _not less_ than `x`.
129 ///
130 /// The slice MUST be ordered by the order defined by its elements.
131 ///
132 /// # Example:
133 ///
134 /// ```
135 /// # use wt_slice::*;
136 /// let a = [10, 11, 13, 13, 15];
137 /// assert_eq!(a.lower_bound(&9), 0);
138 /// assert_eq!(a.lower_bound(&10), 0);
139 /// assert_eq!(a.lower_bound(&11), 1);
140 /// assert_eq!(a.lower_bound(&12), 2);
141 /// assert_eq!(a.lower_bound(&13), 2);
142 /// assert_eq!(a.lower_bound(&14), 4);
143 /// assert_eq!(a.lower_bound(&15), 4);
144 /// assert_eq!(a.lower_bound(&16), 5);
145 /// ```
146 fn lower_bound(&self, x: &Self::Item) -> usize
147 where
148 Self::Item: Ord;
149
150 /// Returns the index `i` pointing to the first element in the ordered slice
151 /// for which `f(self[i]) != Less`.
152 ///
153 /// The slice MUST be ordered by the order defined by the comparator
154 /// function. The comparator function should take an element and return
155 /// `Ordering` that is consistent with the ordering of the slice.
156 ///
157 /// # Example:
158 ///
159 /// ```
160 /// # use wt_slice::*;
161 /// let b = [1, 2, 3, 6, 9, 9];
162 /// assert_eq!(b.lower_bound(&3), b.lower_bound_by(|x| x.cmp(&3)));
163 /// ```
164 fn lower_bound_by<'a, F>(&'a self, f: F) -> usize
165 where
166 F: FnMut(&'a Self::Item) -> Ordering;
167
168 /// Returns the index `i` pointing to the first element in the ordered slice
169 /// for which `f(self[i]) >= k`.
170 ///
171 /// The slice MUST be ordered by the order defined by the keys of its
172 /// elements.
173 ///
174 /// # Example:
175 ///
176 /// ```
177 /// # use wt_slice::*;
178 /// let b = [1, 2, 3, 6, 9, 9];
179 /// assert_eq!(b.lower_bound(&3), b.lower_bound_by_key(&6, |x| x * 2));
180 /// ```
181 fn lower_bound_by_key<'a, K, F>(&'a self, k: &K, f: F) -> usize
182 where
183 F: FnMut(&'a Self::Item) -> K,
184 K: Ord;
185
186 /// Returns the index `i` pointing to the first element in the ordered slice
187 /// that is _greater_ than `x`.
188 ///
189 /// The slice MUST be ordered by the order defined by its elements.
190 ///
191 /// # Example:
192 ///
193 /// ```
194 /// # use wt_slice::*;
195 /// let a = [10, 11, 13, 13, 15];
196 /// assert_eq!(a.upper_bound(&9), 0);
197 /// assert_eq!(a.upper_bound(&10), 1);
198 /// assert_eq!(a.upper_bound(&11), 2);
199 /// assert_eq!(a.upper_bound(&12), 2);
200 /// assert_eq!(a.upper_bound(&13), 4);
201 /// assert_eq!(a.upper_bound(&14), 4);
202 /// assert_eq!(a.upper_bound(&15), 5);
203 /// assert_eq!(a.upper_bound(&16), 5);
204 /// ```
205 fn upper_bound(&self, x: &Self::Item) -> usize
206 where
207 Self::Item: Ord;
208
209 /// Returns the index `i` pointing to the first element in the ordered slice
210 /// for which `f(self[i]) == Greater`.
211 ///
212 /// The slice MUST be ordered by the order defined by the comparator
213 /// function. The comparator function should take an element and return
214 /// `Ordering` that is consistent with the ordering of the slice.
215 ///
216 /// # Example:
217 ///
218 /// ```
219 /// # use wt_slice::*;
220 /// let b = [1, 2, 3, 6, 9, 9];
221 /// assert_eq!(b.upper_bound(&3), b.upper_bound_by(|x| x.cmp(&3)));
222 /// ```
223 fn upper_bound_by<'a, F>(&'a self, f: F) -> usize
224 where
225 F: FnMut(&'a Self::Item) -> Ordering;
226
227 /// Returns the index `i` pointing to the first element in the ordered slice
228 /// for which `f(self[i]) > k`.
229 ///
230 /// The slice MUST be ordered by the order defined by the keys of its
231 /// elements.
232 ///
233 /// # Example:
234 ///
235 /// ```
236 /// # use wt_slice::*;
237 /// let b = [1, 2, 3, 6, 9, 9];
238 /// assert_eq!(b.lower_bound(&3), b.lower_bound_by_key(&6, |x| x * 2));
239 fn upper_bound_by_key<'a, K, F>(&'a self, k: &K, f: F) -> usize
240 where
241 F: FnMut(&'a Self::Item) -> K,
242 K: Ord;
243
244 /// Returns the [`Range`] `a..b` such that all elements in `self[a..b]` are
245 /// _equal_ to `x`.
246 ///
247 /// The slice MUST be ordered by the order defined by its elements.
248 ///
249 /// # Example:
250 ///
251 /// ```
252 /// # use wt_slice::*;
253 /// let b = [10, 11, 13, 13, 15];
254 /// for i in 9..17 {
255 /// assert_eq!(b.equal_range(&i), (b.lower_bound(&i)..b.upper_bound(&i)));
256 /// }
257 /// ```
258 /// [`Range`]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html
259 fn equal_range(&self, x: &Self::Item) -> core::ops::Range<usize>
260 where
261 Self::Item: Ord;
262
263 /// Returns the [`Range`] `a..b` such that for all elements `e` in `self[a..b]`
264 /// `f(e) == Equal`.
265 ///
266 /// The slice MUST be ordered by the order defined by the comparator
267 /// function. The comparator function should take an element and return
268 /// `Ordering` that is consistent with the ordering of the slice.
269 ///
270 /// # Example:
271 ///
272 /// ```
273 /// # use wt_slice::*;
274 /// let b = [10, 11, 13, 13, 15];
275 /// for i in 9..17 {
276 /// assert_eq!(b.equal_range(&i), b.equal_range_by(|x| x.cmp(&i)));
277 /// }
278 /// ```
279 /// [`Range`]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html
280 fn equal_range_by<'a, F>(&'a self, f: F) -> core::ops::Range<usize>
281 where
282 F: FnMut(&'a Self::Item) -> Ordering;
283
284 /// Returns the [`Range`] `a..b` such that for all elements `e` in `self[a..b]`
285 /// `f(e) == k`.
286 ///
287 /// The slice MUST be ordered by the order defined by the keys of its
288 /// elements.
289 ///
290 /// # Example:
291 ///
292 /// ```
293 /// # use wt_slice::*;
294 /// let b = [10, 11, 13, 13, 15];
295 /// for i in 9..17 {
296 /// let i2 = i * 2;
297 /// assert_eq!(b.equal_range(&i), b.equal_range_by_key(&i2, |x| x * 2));
298 /// }
299 /// ```
300 /// [`Range`]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html
301 fn equal_range_by_key<'a, K, F>(&'a self, k: &K, f: F) -> core::ops::Range<usize>
302 where
303 F: FnMut(&'a Self::Item) -> K,
304 K: Ord;
305
306 /// Transforms the slice into the next permutation from the set of all
307 /// permutations that are lexicographically ordered with respect to the
308 /// natural order of T. Returns true if such permutation exists, otherwise
309 /// transforms the range into the first permutation and returns false.
310 ///
311 /// # Example:
312 ///
313 /// ```
314 /// # use wt_slice::*;
315 /// let mut b = [2, 1, 3];
316 /// let mut v = Vec::new();
317 /// for _ in 0..6 {
318 /// let x = b.next_permutation();
319 /// v.push((x, b.to_vec()));
320 /// }
321 /// assert_eq!(v, &[(true, [2, 3, 1].to_vec()),
322 /// (true, [3, 1, 2].to_vec()),
323 /// (true, [3, 2, 1].to_vec()),
324 /// (false, [1, 2, 3].to_vec()),
325 /// (true, [1, 3, 2].to_vec()),
326 /// (true, [2, 1, 3].to_vec())]);
327 fn next_permutation(&mut self) -> bool
328 where
329 Self::Item: Ord;
330
331 /// Transforms the slice into the previous permutation from the set of all
332 /// permutations that are lexicographically ordered with respect to the
333 /// natural order of T. Returns true if such permutation exists, otherwise
334 /// transforms the range into the last permutation and returns false.
335 ///
336 /// # Example:
337 ///
338 /// ```
339 /// # use wt_slice::*;
340 /// let mut b = [2, 1, 3];
341 /// let mut v = Vec::new();
342 /// for _ in 0..6 {
343 /// let x = b.prev_permutation();
344 /// v.push((x, b.to_vec()));
345 /// }
346 /// assert_eq!(v, &[(true, [1, 3, 2].to_vec()),
347 /// (true, [1, 2, 3].to_vec()),
348 /// (false, [3, 2, 1].to_vec()),
349 /// (true, [3, 1, 2].to_vec()),
350 /// (true, [2, 3, 1].to_vec()),
351 /// (true, [2, 1, 3].to_vec())]);
352 fn prev_permutation(&mut self) -> bool
353 where
354 Self::Item: Ord;
355
356 /// Applies `permutation` to the slice. For each element at index `i` the
357 /// following holds:
358 ///
359 /// new_self[i] == old_self[permutation[i]]
360 ///
361 /// The transformation happens in O(N) time and O(1) space. `permutation`
362 /// is mutated during the transformation but it is restored to its original
363 /// state on return.
364 ///
365 /// # Panics
366 ///
367 /// This function panics if `self` and `permutation` do not have the same
368 /// length or any value in `permutation` is not in `0..self.len()`.
369 ///
370 /// # Example:
371 ///
372 /// ```
373 /// # use wt_slice::*;
374 /// let mut b = ['d', 'a', 'c', 'b'];
375 /// let mut p = [1, 3, 2, 0];
376 /// b.apply_permutation(&mut p);
377 /// assert_eq!(b, ['a', 'b', 'c', 'd']);
378 /// assert_eq!(p, [1, 3, 2, 0]);
379 fn apply_permutation(&mut self, permutation: &mut [isize]);
380
381 /// Applies the inverse of `permutation` to the slice. For each element at
382 /// index `i` the following holds:
383 ///
384 /// new_self[permutation[i]] == old_self[i]
385 ///
386 /// The transformation happens in O(N) time and O(1) space. `permutation`
387 /// is mutated during the transformation but it is restored to its original
388 /// state on return.
389 ///
390 /// # Panics
391 ///
392 /// This function panics if `self` and `permutation` do not have the same
393 /// length or any value in `permutation` is not in `0..self.len()`.
394 ///
395 /// # Example:
396 ///
397 /// ```
398 /// # use wt_slice::*;
399 /// let mut b = ['d', 'a', 'c', 'b'];
400 /// let mut p = [3, 0, 2, 1];
401 /// b.apply_inverse_permutation(&mut p);
402 /// assert_eq!(b, ['a', 'b', 'c', 'd']);
403 /// assert_eq!(p, [3, 0, 2, 1]);
404 fn apply_inverse_permutation(&mut self, permutation: &mut [isize]);
405}
406
407impl<T> Ext for [T] {
408 type Item = T;
409
410 fn lower_bound(&self, x: &Self::Item) -> usize
411 where
412 T: Ord,
413 {
414 self.lower_bound_by(|y| y.cmp(x))
415 }
416 fn lower_bound_by<'a, F>(&'a self, mut f: F) -> usize
417 where
418 F: FnMut(&'a Self::Item) -> Ordering,
419 {
420 let s = self;
421 let mut size = s.len();
422 if size == 0 {
423 return 0;
424 }
425 let mut base = 0usize;
426 while size > 1 {
427 let half = size / 2;
428 let mid = base + half;
429 let cmp = f(unsafe { s.get_unchecked(mid) });
430 base = if cmp == Less { mid } else { base };
431 size -= half;
432 }
433 let cmp = f(unsafe { s.get_unchecked(base) });
434 base + (cmp == Less) as usize
435 }
436 fn lower_bound_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> usize
437 where
438 F: FnMut(&'a Self::Item) -> K,
439 K: Ord,
440 {
441 self.lower_bound_by(|e| f(e).cmp(k))
442 }
443
444 fn upper_bound(&self, x: &Self::Item) -> usize
445 where
446 T: Ord,
447 {
448 self.upper_bound_by(|y| y.cmp(x))
449 }
450
451 fn upper_bound_by<'a, F>(&'a self, mut f: F) -> usize
452 where
453 F: FnMut(&'a Self::Item) -> Ordering,
454 {
455 let s = self;
456 let mut size = s.len();
457 if size == 0 {
458 return 0;
459 }
460 let mut base = 0usize;
461 while size > 1 {
462 let half = size / 2;
463 let mid = base + half;
464 let cmp = f(unsafe { s.get_unchecked(mid) });
465 base = if cmp == Greater { base } else { mid };
466 size -= half;
467 }
468 let cmp = f(unsafe { s.get_unchecked(base) });
469 base + (cmp != Greater) as usize
470 }
471 fn upper_bound_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> usize
472 where
473 F: FnMut(&'a Self::Item) -> K,
474 K: Ord,
475 {
476 self.upper_bound_by(|e| f(e).cmp(k))
477 }
478
479 fn equal_range(&self, x: &Self::Item) -> core::ops::Range<usize>
480 where
481 T: Ord,
482 {
483 self.equal_range_by(|y| y.cmp(x))
484 }
485 fn equal_range_by<'a, F>(&'a self, mut f: F) -> core::ops::Range<usize>
486 where
487 F: FnMut(&'a Self::Item) -> Ordering,
488 {
489 let s = self;
490 let mut size = s.len();
491 if size == 0 {
492 return 0..0;
493 }
494 let mut base = (0usize, 0usize);
495 while size > 1 {
496 let half = size / 2;
497 let mid = (base.0 + half, base.1 + half);
498 let cmp = (
499 f(unsafe { s.get_unchecked(mid.0) }),
500 f(unsafe { s.get_unchecked(mid.1) }),
501 );
502 base = (
503 if cmp.0 == Less { mid.0 } else { base.0 },
504 if cmp.1 == Greater { base.1 } else { mid.1 },
505 );
506 size -= half;
507 }
508 let cmp = (
509 f(unsafe { s.get_unchecked(base.0) }),
510 f(unsafe { s.get_unchecked(base.1) }),
511 );
512 base.0 + (cmp.0 == Less) as usize..base.1 + (cmp.1 != Greater) as usize
513 }
514
515 fn equal_range_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> core::ops::Range<usize>
516 where
517 F: FnMut(&'a Self::Item) -> K,
518 K: Ord,
519 {
520 self.equal_range_by(|e| f(e).cmp(k))
521 }
522
523 fn next_permutation(&mut self) -> bool
524 where
525 Self::Item: Ord
526 {
527 // Adapted from http://en.cppreference.com/w/cpp/algorithm/next_permutation.
528 if self.len() <= 1 { return false; }
529 let last = self.len() - 1;
530 let mut a = last;
531 loop {
532 let mut b = a;
533 a -= 1;
534 if self[a] < self[b] {
535 b = last;
536 while self[a] >= self[b] {
537 b -= 1;
538 }
539 self.swap(a, b);
540 self[a+1..].reverse();
541 return true;
542 }
543 if a == 0 {
544 self.reverse();
545 return false;
546 }
547 }
548 }
549
550 fn prev_permutation(&mut self) -> bool
551 where
552 Self::Item: Ord
553 {
554 // Adapted from http://en.cppreference.com/w/cpp/algorithm/prev_permutation.
555 if self.len() <= 1 { return false; }
556 let last = self.len() - 1;
557 let mut a = last;
558 loop {
559 let mut b = a;
560 a -= 1;
561 if self[b] < self[a] {
562 b = last;
563 while self[b] >= self[a] {
564 b -= 1;
565 }
566 self.swap(a, b);
567 self[a+1..].reverse();
568 return true;
569 }
570 if a == 0 {
571 self.reverse();
572 return false;
573 }
574 }
575 }
576
577 fn apply_permutation(&mut self, perm: &mut [isize]) {
578 assert_eq!(self.len(), perm.len());
579 assert!(self.len() < isize::MAX as usize);
580 for i in 0..self.len() as isize {
581 let mut c = perm[i as usize];
582 if c < 0 {
583 perm[i as usize] = !c;
584 } else if i != c {
585 loop {
586 let n = perm[c as usize];
587 self.swap(c as usize, n as usize);
588 perm[c as usize] = !n;
589 c = n;
590 if i == c { break; }
591 }
592 }
593 }
594 }
595
596 fn apply_inverse_permutation(&mut self, perm: &mut [isize]) {
597 assert_eq!(self.len(), perm.len());
598 assert!(self.len() < isize::MAX as usize);
599 for i in 0..self.len() as isize {
600 let mut c = perm[i as usize];
601 if c < 0 {
602 perm[i as usize] = !c;
603 } else if i != c {
604 loop {
605 self.swap(c as usize, i as usize);
606 let n = perm[c as usize];
607 perm[c as usize] = !n;
608 c = n;
609 if i == c { break; }
610 }
611 }
612 }
613 }
614}
615
616pub trait Ext2 {
617 /// Transforms the slice in the inverse permutation.
618 ///
619 /// # Panics
620 ///
621 /// This function panics if any value in `self` is not in `0..self.len()`.
622 ///
623 /// # Example:
624 ///
625 /// ```
626 /// # use wt_slice::*;
627 /// let mut p = [1, 3, 2, 0];
628 /// p.invert_permutation();
629 /// assert_eq!(p, [3, 0, 2, 1]);
630 fn invert_permutation(&mut self);
631}
632
633impl Ext2 for [isize] {
634 fn invert_permutation(&mut self) {
635 assert!(self.len() < isize::MAX as usize);
636 for i in 0..self.len() as isize {
637 let mut c = self[i as usize];
638 if c < 0 {
639 self[i as usize] = !c;
640 } else if i != c {
641 let mut n = i;
642 loop {
643 let t = self[c as usize];
644 self[c as usize] = !n;
645 n = c;
646 c = t;
647 if c == i {
648 self[i as usize] = n;
649 break;
650 }
651 }
652 }
653 }
654 }
655}
656
657#[cfg(test)]
658mod tests {
659 extern crate std;
660
661 use super::{ExactSearch, Ext};
662
663 #[test]
664 fn exact_search_matches_insertion_semantics() {
665 for size in 0..=128 {
666 let values: std::vec::Vec<u32> = (0..size).map(|value| value * 2 + 2).collect();
667 for needle in 0..=(size * 2 + 4) {
668 let insertion = values.partition_point(|candidate| candidate < &needle);
669 let expected = match values.get(insertion) {
670 Some(candidate) if candidate == &needle => Ok(insertion),
671 _ => Err(insertion),
672 };
673
674 assert_eq!(values.exact_search(&needle), expected, "size={size}, needle={needle}");
675 assert_eq!(
676 values.exact_search_by(|candidate| candidate.cmp(&needle)),
677 expected,
678 "size={size}, needle={needle}",
679 );
680 assert_eq!(
681 values.exact_search_by_key(&needle, |candidate| *candidate),
682 expected,
683 "size={size}, needle={needle}",
684 );
685 }
686 }
687 }
688
689 #[test]
690 fn exact_search_accepts_any_equal_duplicate() {
691 let values = [1, 3, 3, 3, 5];
692 let found = values.exact_search(&3).unwrap();
693 assert_eq!(values[found], 3);
694 }
695
696 #[test]
697 fn lower_bound() {
698 let b: [u32; 0] = [];
699 assert_eq!(b.lower_bound(&0), 0);
700 let b = [1, 3, 3, 5];
701 assert_eq!(b.lower_bound(&0), 0);
702 assert_eq!(b.lower_bound(&1), 0);
703 assert_eq!(b.lower_bound(&2), 1);
704 assert_eq!(b.lower_bound(&3), 1);
705 assert_eq!(b.lower_bound(&4), 3);
706 assert_eq!(b.lower_bound(&5), 3);
707 assert_eq!(b.lower_bound(&6), 4);
708 }
709
710 #[test]
711 fn upper_bound() {
712 let b: [u32; 0] = [];
713 assert_eq!(b.upper_bound(&0), 0);
714 let b = [1, 3, 3, 5];
715 assert_eq!(b.upper_bound(&0), 0);
716 assert_eq!(b.upper_bound(&1), 1);
717 assert_eq!(b.upper_bound(&2), 1);
718 assert_eq!(b.upper_bound(&3), 3);
719 assert_eq!(b.upper_bound(&4), 3);
720 assert_eq!(b.upper_bound(&5), 4);
721 assert_eq!(b.upper_bound(&6), 4);
722 }
723
724 #[test]
725 fn equal_range() {
726 let b: [u32; 0] = [];
727 assert_eq!(b.equal_range(&0), 0..0);
728 let b = [1, 3, 3, 5];
729 assert_eq!(b.equal_range(&0), 0..0);
730 assert_eq!(b.equal_range(&1), 0..1);
731 assert_eq!(b.equal_range(&2), 1..1);
732 assert_eq!(b.equal_range(&3), 1..3);
733 assert_eq!(b.equal_range(&4), 3..3);
734 assert_eq!(b.equal_range(&5), 3..4);
735 assert_eq!(b.equal_range(&6), 4..4);
736 }
737}