seekable_iterator/
comparator.rs

1use core::cmp::Ordering;
2
3#[cfg(feature = "clone-behavior")]
4use clone_behavior::{DeepClone, MirroredClone, Speed};
5#[cfg(feature = "generic-container")]
6use generic_container::{FragileContainer, GenericContainer};
7
8
9/// Interface for comparing keys (or entries) of a sorted collection.
10///
11/// The comparison function should provide a total order, just as [`Ord`] would. Additionally,
12/// any clones of a comparator value should behave identically to the source comparator.
13///
14/// Note that none of the axioms that define a total order require that two elements which compare
15/// as equal are "*truly*" equal in some more fundamental sense; that is, keys which are distinct
16/// (perhaps according to an [`Eq`] implementation) may compare as equal in the provided total
17/// order and corresponding equivalence relation.
18///
19/// Unsafe code is *not* allowed to rely on the correctness of implementations; that is, an
20/// incorrect `Comparator` implementation may cause severe logic errors, but must not cause
21/// memory unsafety.
22pub trait Comparator<Key: ?Sized> {
23    /// Compare two keys (or entries) in a sorted collection.
24    ///
25    /// This method is analogous to [`Ord::cmp`], and should provide a total order.
26    ///
27    /// Note that none of the axioms that define a total order require that two elements which
28    /// compare as equal are "*truly*" equal in some more fundamental sense; that is, keys which
29    /// are distinct (perhaps according to an [`Eq`] implementation) may compare as equal in
30    /// the provided total order and corresponding equivalence relation.
31    ///
32    /// Unsafe code is *not* allowed to rely on the correctness of implementations; that is, an
33    /// incorrect implementation may cause severe logic errors, but must not cause
34    /// memory unsafety.
35    #[must_use]
36    fn cmp(&self, lhs: &Key, rhs: &Key) -> Ordering;
37}
38
39#[cfg(feature = "generic-container")]
40impl<Key: ?Sized, C: FragileContainer<dyn Comparator<Key>>> Comparator<Key> for C {
41    #[inline]
42    fn cmp(&self, lhs: &Key, rhs: &Key) -> Ordering {
43        // I'm slightly paranoid about the type coercion coercing to the wrong thing,
44        // but doing this line-by-line is probably unnecessary.
45        let inner = self.get_ref();
46        let inner: &dyn Comparator<Key> = &*inner;
47        inner.cmp(lhs, rhs)
48    }
49}
50
51#[cfg(feature = "generic-container")]
52impl<T, C, Key> Comparator<Key> for GenericContainer<T, C>
53where
54    T:   ?Sized + Comparator<Key>,
55    C:   ?Sized + FragileContainer<T>,
56    Key: ?Sized,
57{
58    #[inline]
59    fn cmp(&self, lhs: &Key, rhs: &Key) -> Ordering {
60        let inner = self.container.get_ref();
61        let inner: &T = &inner;
62        inner.cmp(lhs, rhs)
63    }
64}
65
66/// A [`Comparator`] which uses keys' [`Ord`] implementations.
67#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
68pub struct OrdComparator;
69
70impl<Key: ?Sized + Ord> Comparator<Key> for OrdComparator {
71    /// Equivalent to `Ord::cmp(lhs, rhs)`.
72    #[inline]
73    fn cmp(&self, lhs: &Key, rhs: &Key) -> Ordering {
74        Ord::cmp(lhs, rhs)
75    }
76}
77
78#[cfg(feature = "clone-behavior")]
79impl<S: Speed> DeepClone<S> for OrdComparator {
80    #[inline]
81    fn deep_clone(&self) -> Self {
82        Self
83    }
84}
85
86#[cfg(feature = "clone-behavior")]
87impl<S: Speed> MirroredClone<S> for OrdComparator {
88    #[inline]
89    fn mirrored_clone(&self) -> Self {
90        Self
91    }
92}