Skip to main content

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}