Skip to main content

qubit_function/comparator/
fn_comparator_ops.rs

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