Skip to main content

qubit_function/comparator/
fn_comparator_ops.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `FnComparatorOps` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15/// Extension trait providing composition methods for closures and function
16/// pointers.
17///
18/// This trait is automatically implemented for all closures and function
19/// pointers with the signature `Fn(&T, &T) -> Ordering`, allowing them to
20/// be composed directly without explicit wrapping.
21///
22/// # Examples
23///
24/// ```rust
25/// use qubit_function::comparator::{Comparator, FnComparatorOps, BoxComparator};
26/// use std::cmp::Ordering;
27///
28/// let cmp = (|a: &i32, b: &i32| a.cmp(b))
29///     .reversed()
30///     .then_comparing(BoxComparator::new(|a: &i32, b: &i32| b.cmp(a)));
31///
32/// assert_eq!(cmp.compare(&5, &3), Ordering::Less);
33/// ```
34///
35/// # Author
36///
37/// Haixing Hu
38pub trait FnComparatorOps<T>: Fn(&T, &T) -> Ordering + Sized {
39    /// Returns a comparator that imposes the reverse ordering.
40    ///
41    /// # Returns
42    ///
43    /// A new `BoxComparator` that reverses the comparison order.
44    ///
45    /// # Examples
46    ///
47    /// ```rust
48    /// use qubit_function::comparator::{Comparator, FnComparatorOps};
49    /// use std::cmp::Ordering;
50    ///
51    /// let rev = (|a: &i32, b: &i32| a.cmp(b)).reversed();
52    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
53    /// ```
54    #[inline]
55    fn reversed(self) -> BoxComparator<T>
56    where
57        Self: 'static,
58        T: 'static,
59    {
60        BoxComparator::new(self).reversed()
61    }
62
63    /// Returns a comparator that uses this comparator first, then another
64    /// comparator if this one considers the values equal.
65    ///
66    /// # Parameters
67    ///
68    /// * `other` - The comparator to use for tie-breaking
69    ///
70    /// # Returns
71    ///
72    /// A new `BoxComparator` that chains this comparator with another.
73    ///
74    /// # Examples
75    ///
76    /// ```rust
77    /// use qubit_function::comparator::{Comparator, FnComparatorOps, BoxComparator};
78    /// use std::cmp::Ordering;
79    ///
80    /// let cmp = (|a: &i32, b: &i32| (a % 2).cmp(&(b % 2)))
81    ///     .then_comparing(BoxComparator::new(|a: &i32, b: &i32| a.cmp(b)));
82    /// assert_eq!(cmp.compare(&4, &2), Ordering::Greater);
83    /// ```
84    #[inline]
85    fn then_comparing(self, other: BoxComparator<T>) -> BoxComparator<T>
86    where
87        Self: 'static,
88        T: 'static,
89    {
90        BoxComparator::new(self).then_comparing(other)
91    }
92}
93
94impl<T, F> FnComparatorOps<T> for F where F: Fn(&T, &T) -> Ordering {}