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 {}