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
13use super::{
14 BoxComparator,
15 Ordering,
16};
17
18/// Extension trait providing composition methods for closures and function
19/// pointers.
20///
21/// This trait is automatically implemented for all closures and function
22/// pointers with the signature `Fn(&T, &T) -> Ordering`, allowing them to
23/// be composed directly without explicit wrapping.
24///
25/// # Examples
26///
27/// ```rust
28/// use qubit_function::comparator::{Comparator, FnComparatorOps, BoxComparator};
29/// use std::cmp::Ordering;
30///
31/// let cmp = (|a: &i32, b: &i32| a.cmp(b))
32/// .reversed()
33/// .then_comparing(BoxComparator::new(|a: &i32, b: &i32| b.cmp(a)));
34///
35/// assert_eq!(cmp.compare(&5, &3), Ordering::Less);
36/// ```
37///
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 {}