Skip to main content

qubit_function/
comparator.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Comparator Abstraction
10//!
11//! Provides a Rust implementation similar to Java's `Comparator` interface
12//! for comparison operations and chaining.
13//!
14//! ## Design Overview
15//!
16//! This module adopts the **Trait + Multiple Implementations** design
17//! pattern, which is the most flexible and elegant approach for
18//! implementing comparators in Rust. It achieves a perfect balance
19//! between semantic clarity, type safety, and API flexibility.
20//!
21//! ### Core Components
22//!
23//! 1. **`Comparator<T>` trait**: A minimalist unified interface that only
24//!    defines the core `compare` method and type conversion methods
25//!    (`into_*`). It does NOT include chaining methods like
26//!    `then_comparing`, etc.
27//!
28//! 2. **Three Concrete Struct Implementations**:
29//!    - [`BoxComparator<T>`]: Box-based single ownership implementation
30//!      for one-time use scenarios
31//!    - [`ArcComparator<T>`]: Arc-based thread-safe shared ownership
32//!      implementation for multi-threaded scenarios
33//!    - [`RcComparator<T>`]: Rc-based single-threaded shared ownership
34//!      implementation for single-threaded reuse
35//!
36//! 3. **Specialized Composition Methods**: Each struct implements its own
37//!    inherent methods (`reversed`, `then_comparing`, etc.) that return
38//!    the same concrete type, preserving their specific characteristics
39//!    (e.g., `ArcComparator` compositions remain `ArcComparator` and stay
40//!    cloneable and thread-safe).
41//!
42//! 4. **Extension Trait for Closures**: The `FnComparatorOps<T>`
43//!    extension trait provides composition methods for all closures and
44//!    function pointers, returning `BoxComparator<T>` to initiate method
45//!    chaining.
46//!
47//! 5. **Unified Trait Implementation**: All closures and the three
48//!    structs implement the `Comparator<T>` trait, enabling them to be
49//!    handled uniformly by generic functions.
50//!
51//! ## Ownership Model Coverage
52//!
53//! The three implementations correspond to three typical ownership
54//! scenarios:
55//!
56//! | Type | Ownership | Clonable | Thread-Safe | API | Use Case |
57//! |:-----|:----------|:---------|:------------|:----|:---------|
58//! | [`BoxComparator`] | Single | ❌ | ❌ | consumes `self` | One-time |
59//! | [`ArcComparator`] | Shared | ✅ | ✅ | borrows `&self` | Multi-thread |
60//! | [`RcComparator`] | Shared | ✅ | ❌ | borrows `&self` | Single-thread |
61//!
62//! ## Key Design Advantages
63//!
64//! ### 1. Type Preservation through Specialization
65//!
66//! By implementing composition methods on concrete structs rather than in
67//! the trait, each type maintains its specific characteristics through
68//! composition:
69//!
70//! ```rust
71//! use qubit_function::comparator::{Comparator, ArcComparator};
72//! use std::cmp::Ordering;
73//!
74//! let arc_cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
75//! let another = ArcComparator::new(|a: &i32, b: &i32| b.cmp(a));
76//!
77//! // Composition returns ArcComparator, preserving clonability and
78//! // thread-safety
79//! let combined = arc_cmp.then_comparing(&another);
80//! let cloned = combined.clone();  // ✅ Still cloneable
81//!
82//! // Original comparators remain usable
83//! assert_eq!(arc_cmp.compare(&5, &3), Ordering::Greater);
84//! ```
85//!
86//! ### 2. Elegant API without Explicit Cloning
87//!
88//! `ArcComparator` and `RcComparator` use `&self` in their composition
89//! methods, providing a natural experience without requiring explicit
90//! `.clone()` calls:
91//!
92//! ```rust
93//! use qubit_function::comparator::{Comparator, ArcComparator};
94//!
95//! let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
96//!
97//! // No need for explicit clone()
98//! let reversed = cmp.reversed();
99//! let chained = cmp.then_comparing(&ArcComparator::new(|a, b| b.cmp(a)));
100//!
101//! // cmp is still available
102//! cmp.compare(&1, &2);
103//! ```
104//!
105//! ### 3. Efficient Closure Composition
106//!
107//! The `FnComparatorOps` extension trait allows direct composition on
108//! closures:
109//!
110//! ```rust
111//! use qubit_function::comparator::{Comparator, FnComparatorOps};
112//! use std::cmp::Ordering;
113//!
114//! let cmp = (|a: &i32, b: &i32| a.cmp(b))
115//!     .reversed()
116//!     .then_comparing(|a: &i32, b: &i32| b.cmp(a));
117//!
118//! assert_eq!(cmp.compare(&5, &3), Ordering::Less);
119//! ```
120//!
121//! ## Usage Examples
122//!
123//! ### Basic Comparison
124//!
125//! ```rust
126//! use qubit_function::comparator::{Comparator, BoxComparator};
127//! use std::cmp::Ordering;
128//!
129//! let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
130//! assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
131//! ```
132//!
133//! ### Reversed Comparison
134//!
135//! ```rust
136//! use qubit_function::comparator::{Comparator, BoxComparator};
137//! use std::cmp::Ordering;
138//!
139//! let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
140//! let rev = cmp.reversed();
141//! assert_eq!(rev.compare(&5, &3), Ordering::Less);
142//! ```
143//!
144//! ### Chained Comparison
145//!
146//! ```rust
147//! use qubit_function::comparator::{Comparator, BoxComparator};
148//! use std::cmp::Ordering;
149//!
150//! #[derive(Debug)]
151//! struct Person {
152//!     name: String,
153//!     age: i32,
154//! }
155//!
156//! let by_name = BoxComparator::new(|a: &Person, b: &Person| {
157//!     a.name.cmp(&b.name)
158//! });
159//! let by_age = BoxComparator::new(|a: &Person, b: &Person| {
160//!     a.age.cmp(&b.age)
161//! });
162//! let cmp = by_name.then_comparing(by_age);
163//!
164//! let p1 = Person { name: "Alice".to_string(), age: 30 };
165//! let p2 = Person { name: "Alice".to_string(), age: 25 };
166//! assert_eq!(cmp.compare(&p1, &p2), Ordering::Greater);
167//! ```
168//!
169//! ## Author
170//!
171//! Haixing Hu
172use std::cmp::Ordering;
173use std::rc::Rc;
174use std::sync::Arc;
175
176// ==========================================================================
177// Type Aliases
178// ==========================================================================
179
180/// A trait for comparison operations.
181///
182/// This trait defines the core comparison operation and conversion methods.
183/// It does NOT include composition methods like `reversed` or
184/// `then_comparing` to maintain a clean separation between the trait
185/// interface and specialized implementations.
186///
187/// # Type Parameters
188///
189/// * `T` - The type of values being compared
190///
191/// # Examples
192///
193/// ```rust
194/// use qubit_function::comparator::{Comparator, BoxComparator};
195/// use std::cmp::Ordering;
196///
197/// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
198/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
199/// ```
200///
201/// # Author
202///
203/// Haixing Hu
204pub trait Comparator<T> {
205    /// Compares two values and returns an ordering.
206    ///
207    /// # Parameters
208    ///
209    /// * `a` - The first value to compare
210    /// * `b` - The second value to compare
211    ///
212    /// # Returns
213    ///
214    /// An `Ordering` indicating whether `a` is less than, equal to, or
215    /// greater than `b`.
216    ///
217    /// # Examples
218    ///
219    /// ```rust
220    /// use qubit_function::comparator::{Comparator, BoxComparator};
221    /// use std::cmp::Ordering;
222    ///
223    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
224    /// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
225    /// assert_eq!(cmp.compare(&3, &5), Ordering::Less);
226    /// assert_eq!(cmp.compare(&5, &5), Ordering::Equal);
227    /// ```
228    fn compare(&self, a: &T, b: &T) -> Ordering;
229
230    /// Converts this comparator into a `BoxComparator`.
231    ///
232    /// # Returns
233    ///
234    /// A new `BoxComparator` wrapping this comparator.
235    ///
236    /// # Examples
237    ///
238    /// ```rust
239    /// use qubit_function::comparator::{Comparator, BoxComparator};
240    ///
241    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
242    /// let boxed = cmp.into_box();
243    /// ```
244    #[inline]
245    fn into_box(self) -> BoxComparator<T>
246    where
247        Self: Sized + 'static,
248        T: 'static,
249    {
250        BoxComparator::new(move |a, b| self.compare(a, b))
251    }
252
253    /// Converts this comparator into an `ArcComparator`.
254    ///
255    /// # Returns
256    ///
257    /// A new `ArcComparator` wrapping this comparator.
258    ///
259    /// # Examples
260    ///
261    /// ```rust
262    /// use qubit_function::comparator::{Comparator, ArcComparator};
263    ///
264    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
265    /// let arc = cmp.into_arc();
266    /// ```
267    #[inline]
268    fn into_arc(self) -> ArcComparator<T>
269    where
270        Self: Sized + Send + Sync + 'static,
271        T: 'static,
272    {
273        ArcComparator::new(move |a, b| self.compare(a, b))
274    }
275
276    /// Converts this comparator into an `RcComparator`.
277    ///
278    /// # Returns
279    ///
280    /// A new `RcComparator` wrapping this comparator.
281    ///
282    /// # Examples
283    ///
284    /// ```rust
285    /// use qubit_function::comparator::{Comparator, RcComparator};
286    ///
287    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
288    /// let rc = cmp.into_rc();
289    /// ```
290    #[inline]
291    fn into_rc(self) -> RcComparator<T>
292    where
293        Self: Sized + 'static,
294        T: 'static,
295    {
296        RcComparator::new(move |a, b| self.compare(a, b))
297    }
298
299    /// Converts this comparator into a closure that implements
300    /// `Fn(&T, &T) -> Ordering`.
301    ///
302    /// This method consumes the comparator and returns a closure that
303    /// can be used anywhere a function or closure is expected.
304    ///
305    /// # Returns
306    ///
307    /// An implementation that can be called as `Fn(&T, &T) -> Ordering`.
308    ///
309    /// # Examples
310    ///
311    /// ```rust
312    /// use qubit_function::comparator::{Comparator, BoxComparator};
313    /// use std::cmp::Ordering;
314    ///
315    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
316    /// let func = cmp.into_fn();
317    /// assert_eq!(func(&5, &3), Ordering::Greater);
318    /// ```
319    #[inline]
320    fn into_fn(self) -> impl Fn(&T, &T) -> Ordering
321    where
322        Self: Sized + 'static,
323        T: 'static,
324    {
325        move |a: &T, b: &T| self.compare(a, b)
326    }
327}
328
329/// Blanket implementation of `Comparator` for all closures and function
330/// pointers.
331///
332/// This allows any closure or function with the signature
333/// `Fn(&T, &T) -> Ordering` to be used as a comparator.
334///
335/// # Examples
336///
337/// ```rust
338/// use qubit_function::comparator::Comparator;
339/// use std::cmp::Ordering;
340///
341/// let cmp = |a: &i32, b: &i32| a.cmp(b);
342/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
343/// ```
344impl<T, F> Comparator<T> for F
345where
346    F: Fn(&T, &T) -> Ordering,
347{
348    #[inline]
349    fn compare(&self, a: &T, b: &T) -> Ordering {
350        self(a, b)
351    }
352}
353
354/// A boxed comparator with single ownership.
355///
356/// `BoxComparator` wraps a comparator function in a `Box`, providing single
357/// ownership semantics. It is not cloneable and consumes `self` in
358/// composition operations.
359///
360/// # Type Parameters
361///
362/// * `T` - The type of values being compared
363///
364/// # Examples
365///
366/// ```rust
367/// use qubit_function::comparator::{Comparator, BoxComparator};
368/// use std::cmp::Ordering;
369///
370/// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
371/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
372/// ```
373///
374/// # Author
375///
376/// Haixing Hu
377pub struct BoxComparator<T> {
378    function: Box<dyn Fn(&T, &T) -> Ordering>,
379}
380
381impl<T: 'static> BoxComparator<T> {
382    /// Creates a new `BoxComparator` from a closure.
383    ///
384    /// # Parameters
385    ///
386    /// * `f` - The closure to wrap
387    ///
388    /// # Returns
389    ///
390    /// A new `BoxComparator` instance.
391    ///
392    /// # Examples
393    ///
394    /// ```rust
395    /// use qubit_function::comparator::BoxComparator;
396    ///
397    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
398    /// ```
399    #[inline]
400    pub fn new<F>(f: F) -> Self
401    where
402        F: Fn(&T, &T) -> Ordering + 'static,
403    {
404        Self {
405            function: Box::new(f),
406        }
407    }
408
409    /// Returns a comparator that imposes the reverse ordering.
410    ///
411    /// # Returns
412    ///
413    /// A new `BoxComparator` that reverses the comparison order.
414    ///
415    /// # Examples
416    ///
417    /// ```rust
418    /// use qubit_function::comparator::{Comparator, BoxComparator};
419    /// use std::cmp::Ordering;
420    ///
421    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
422    /// let rev = cmp.reversed();
423    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
424    /// ```
425    #[inline]
426    pub fn reversed(self) -> Self {
427        BoxComparator::new(move |a, b| (self.function)(b, a))
428    }
429
430    /// Returns a comparator that uses this comparator first, then another
431    /// comparator if this one considers the values equal.
432    ///
433    /// # Parameters
434    ///
435    /// * `other` - The comparator to use for tie-breaking. **Note: This
436    ///   parameter is passed by value and will transfer ownership.** If you
437    ///   need to preserve the original comparator, clone it first (if it
438    ///   implements `Clone`). Can be:
439    ///   - A `BoxComparator<T>`
440    ///   - An `RcComparator<T>`
441    ///   - An `ArcComparator<T>`
442    ///   - Any type implementing `Comparator<T>`
443    ///
444    /// # Returns
445    ///
446    /// A new `BoxComparator` that chains this comparator with another.
447    ///
448    /// # Examples
449    ///
450    /// ```rust
451    /// use qubit_function::comparator::{Comparator, BoxComparator};
452    /// use std::cmp::Ordering;
453    ///
454    /// #[derive(Debug)]
455    /// struct Person {
456    ///     name: String,
457    ///     age: i32,
458    /// }
459    ///
460    /// let by_name = BoxComparator::new(|a: &Person, b: &Person| {
461    ///     a.name.cmp(&b.name)
462    /// });
463    /// let by_age = BoxComparator::new(|a: &Person, b: &Person| {
464    ///     a.age.cmp(&b.age)
465    /// });
466    ///
467    /// // by_age is moved here
468    /// let cmp = by_name.then_comparing(by_age);
469    ///
470    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
471    /// let p2 = Person { name: "Alice".to_string(), age: 25 };
472    /// assert_eq!(cmp.compare(&p1, &p2), Ordering::Greater);
473    /// // by_age.compare(&p1, &p2); // Would not compile - moved
474    /// ```
475    #[inline]
476    pub fn then_comparing(self, other: Self) -> Self {
477        BoxComparator::new(move |a, b| match (self.function)(a, b) {
478            Ordering::Equal => (other.function)(a, b),
479            ord => ord,
480        })
481    }
482
483    /// Returns a comparator that compares values by a key extracted by the
484    /// given function.
485    ///
486    /// # Parameters
487    ///
488    /// * `key_fn` - A function that extracts a comparable key from values
489    ///
490    /// # Returns
491    ///
492    /// A new `BoxComparator` that compares by the extracted key.
493    ///
494    /// # Examples
495    ///
496    /// ```rust
497    /// use qubit_function::comparator::{Comparator, BoxComparator};
498    /// use std::cmp::Ordering;
499    ///
500    /// #[derive(Debug)]
501    /// struct Person {
502    ///     name: String,
503    ///     age: i32,
504    /// }
505    ///
506    /// let by_age = BoxComparator::comparing(|p: &Person| &p.age);
507    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
508    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
509    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
510    /// ```
511    #[inline]
512    pub fn comparing<K, F>(key_fn: F) -> Self
513    where
514        K: Ord,
515        F: Fn(&T) -> &K + 'static,
516    {
517        BoxComparator::new(move |a: &T, b: &T| key_fn(a).cmp(key_fn(b)))
518    }
519
520    /// Converts this comparator into a closure.
521    ///
522    /// # Returns
523    ///
524    /// A closure that implements `Fn(&T, &T) -> Ordering`.
525    ///
526    /// # Examples
527    ///
528    /// ```rust
529    /// use qubit_function::comparator::{Comparator, BoxComparator};
530    /// use std::cmp::Ordering;
531    ///
532    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
533    /// let func = cmp.into_fn();
534    /// assert_eq!(func(&5, &3), Ordering::Greater);
535    /// ```
536    #[inline]
537    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
538        move |a: &T, b: &T| (self.function)(a, b)
539    }
540}
541
542impl<T> Comparator<T> for BoxComparator<T> {
543    #[inline]
544    fn compare(&self, a: &T, b: &T) -> Ordering {
545        (self.function)(a, b)
546    }
547}
548
549/// An Arc-based thread-safe comparator with shared ownership.
550///
551/// `ArcComparator` wraps a comparator function in an `Arc`, providing
552/// thread-safe shared ownership semantics. It is cloneable and uses `&self`
553/// in composition operations.
554///
555/// # Type Parameters
556///
557/// * `T` - The type of values being compared
558///
559/// # Examples
560///
561/// ```rust
562/// use qubit_function::comparator::{Comparator, ArcComparator};
563/// use std::cmp::Ordering;
564///
565/// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
566/// let cloned = cmp.clone();
567/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
568/// assert_eq!(cloned.compare(&5, &3), Ordering::Greater);
569/// ```
570///
571/// # Author
572///
573/// Haixing Hu
574#[derive(Clone)]
575pub struct ArcComparator<T> {
576    function: Arc<dyn Fn(&T, &T) -> Ordering + Send + Sync>,
577}
578
579impl<T: 'static> ArcComparator<T> {
580    /// Creates a new `ArcComparator` from a closure.
581    ///
582    /// # Parameters
583    ///
584    /// * `f` - The closure to wrap
585    ///
586    /// # Returns
587    ///
588    /// A new `ArcComparator` instance.
589    ///
590    /// # Examples
591    ///
592    /// ```rust
593    /// use qubit_function::comparator::ArcComparator;
594    ///
595    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
596    /// ```
597    #[inline]
598    pub fn new<F>(f: F) -> Self
599    where
600        F: Fn(&T, &T) -> Ordering + Send + Sync + 'static,
601    {
602        Self {
603            function: Arc::new(f),
604        }
605    }
606
607    /// Returns a comparator that imposes the reverse ordering.
608    ///
609    /// # Returns
610    ///
611    /// A new `ArcComparator` that reverses the comparison order.
612    ///
613    /// # Examples
614    ///
615    /// ```rust
616    /// use qubit_function::comparator::{Comparator, ArcComparator};
617    /// use std::cmp::Ordering;
618    ///
619    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
620    /// let rev = cmp.reversed();
621    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
622    /// assert_eq!(cmp.compare(&5, &3), Ordering::Greater); // cmp still works
623    /// ```
624    #[inline]
625    pub fn reversed(&self) -> Self {
626        let self_fn = self.function.clone();
627        ArcComparator::new(move |a, b| self_fn(b, a))
628    }
629
630    /// Returns a comparator that uses this comparator first, then another
631    /// comparator if this one considers the values equal.
632    ///
633    /// # Parameters
634    ///
635    /// * `other` - The comparator to use for tie-breaking
636    ///
637    /// # Returns
638    ///
639    /// A new `ArcComparator` that chains this comparator with another.
640    ///
641    /// # Examples
642    ///
643    /// ```rust
644    /// use qubit_function::comparator::{Comparator, ArcComparator};
645    /// use std::cmp::Ordering;
646    ///
647    /// let cmp1 = ArcComparator::new(|a: &i32, b: &i32| {
648    ///     (a % 2).cmp(&(b % 2))
649    /// });
650    /// let cmp2 = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
651    /// let chained = cmp1.then_comparing(&cmp2);
652    /// assert_eq!(chained.compare(&4, &2), Ordering::Greater);
653    /// ```
654    #[inline]
655    pub fn then_comparing(&self, other: &Self) -> Self {
656        let first = self.function.clone();
657        let second = other.function.clone();
658        ArcComparator::new(move |a, b| match first(a, b) {
659            Ordering::Equal => second(a, b),
660            ord => ord,
661        })
662    }
663
664    /// Returns a comparator that compares values by a key extracted by the
665    /// given function.
666    ///
667    /// # Parameters
668    ///
669    /// * `key_fn` - A function that extracts a comparable key from values
670    ///
671    /// # Returns
672    ///
673    /// A new `ArcComparator` that compares by the extracted key.
674    ///
675    /// # Examples
676    ///
677    /// ```rust
678    /// use qubit_function::comparator::{Comparator, ArcComparator};
679    /// use std::cmp::Ordering;
680    ///
681    /// #[derive(Debug)]
682    /// struct Person {
683    ///     name: String,
684    ///     age: i32,
685    /// }
686    ///
687    /// let by_age = ArcComparator::comparing(|p: &Person| &p.age);
688    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
689    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
690    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
691    /// ```
692    #[inline]
693    pub fn comparing<K, F>(key_fn: F) -> Self
694    where
695        K: Ord,
696        F: Fn(&T) -> &K + Send + Sync + 'static,
697    {
698        ArcComparator::new(move |a, b| key_fn(a).cmp(key_fn(b)))
699    }
700
701    /// Converts this comparator into a closure.
702    ///
703    /// # Returns
704    ///
705    /// A closure that implements `Fn(&T, &T) -> Ordering`.
706    ///
707    /// # Examples
708    ///
709    /// ```rust
710    /// use qubit_function::comparator::{Comparator, ArcComparator};
711    /// use std::cmp::Ordering;
712    ///
713    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
714    /// let func = cmp.into_fn();
715    /// assert_eq!(func(&5, &3), Ordering::Greater);
716    /// ```
717    #[inline]
718    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
719        move |a: &T, b: &T| (self.function)(a, b)
720    }
721}
722
723impl<T> Comparator<T> for ArcComparator<T> {
724    #[inline]
725    fn compare(&self, a: &T, b: &T) -> Ordering {
726        (self.function)(a, b)
727    }
728}
729
730/// An Rc-based single-threaded comparator with shared ownership.
731///
732/// `RcComparator` wraps a comparator function in an `Rc`, providing
733/// single-threaded shared ownership semantics. It is cloneable and uses
734/// `&self` in composition operations.
735///
736/// # Type Parameters
737///
738/// * `T` - The type of values being compared
739///
740/// # Examples
741///
742/// ```rust
743/// use qubit_function::comparator::{Comparator, RcComparator};
744/// use std::cmp::Ordering;
745///
746/// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
747/// let cloned = cmp.clone();
748/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
749/// assert_eq!(cloned.compare(&5, &3), Ordering::Greater);
750/// ```
751///
752/// # Author
753///
754/// Haixing Hu
755#[derive(Clone)]
756pub struct RcComparator<T> {
757    function: Rc<dyn Fn(&T, &T) -> Ordering>,
758}
759
760impl<T: 'static> RcComparator<T> {
761    /// Creates a new `RcComparator` from a closure.
762    ///
763    /// # Parameters
764    ///
765    /// * `f` - The closure to wrap
766    ///
767    /// # Returns
768    ///
769    /// A new `RcComparator` instance.
770    ///
771    /// # Examples
772    ///
773    /// ```rust
774    /// use qubit_function::comparator::RcComparator;
775    ///
776    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
777    /// ```
778    #[inline]
779    pub fn new<F>(f: F) -> Self
780    where
781        F: Fn(&T, &T) -> Ordering + 'static,
782    {
783        Self {
784            function: Rc::new(f),
785        }
786    }
787
788    /// Returns a comparator that imposes the reverse ordering.
789    ///
790    /// # Returns
791    ///
792    /// A new `RcComparator` that reverses the comparison order.
793    ///
794    /// # Examples
795    ///
796    /// ```rust
797    /// use qubit_function::comparator::{Comparator, RcComparator};
798    /// use std::cmp::Ordering;
799    ///
800    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
801    /// let rev = cmp.reversed();
802    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
803    /// assert_eq!(cmp.compare(&5, &3), Ordering::Greater); // cmp still works
804    /// ```
805    #[inline]
806    pub fn reversed(&self) -> Self {
807        let self_fn = self.function.clone();
808        RcComparator::new(move |a, b| self_fn(b, a))
809    }
810
811    /// Returns a comparator that uses this comparator first, then another
812    /// comparator if this one considers the values equal.
813    ///
814    /// # Parameters
815    ///
816    /// * `other` - The comparator to use for tie-breaking
817    ///
818    /// # Returns
819    ///
820    /// A new `RcComparator` that chains this comparator with another.
821    ///
822    /// # Examples
823    ///
824    /// ```rust
825    /// use qubit_function::comparator::{Comparator, RcComparator};
826    /// use std::cmp::Ordering;
827    ///
828    /// let cmp1 = RcComparator::new(|a: &i32, b: &i32| {
829    ///     (a % 2).cmp(&(b % 2))
830    /// });
831    /// let cmp2 = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
832    /// let chained = cmp1.then_comparing(&cmp2);
833    /// assert_eq!(chained.compare(&4, &2), Ordering::Greater);
834    /// ```
835    #[inline]
836    pub fn then_comparing(&self, other: &Self) -> Self {
837        let first = self.function.clone();
838        let second = other.function.clone();
839        RcComparator::new(move |a, b| match first(a, b) {
840            Ordering::Equal => second(a, b),
841            ord => ord,
842        })
843    }
844
845    /// Returns a comparator that compares values by a key extracted by the
846    /// given function.
847    ///
848    /// # Parameters
849    ///
850    /// * `key_fn` - A function that extracts a comparable key from values
851    ///
852    /// # Returns
853    ///
854    /// A new `RcComparator` that compares by the extracted key.
855    ///
856    /// # Examples
857    ///
858    /// ```rust
859    /// use qubit_function::comparator::{Comparator, RcComparator};
860    /// use std::cmp::Ordering;
861    ///
862    /// #[derive(Debug)]
863    /// struct Person {
864    ///     name: String,
865    ///     age: i32,
866    /// }
867    ///
868    /// let by_age = RcComparator::comparing(|p: &Person| &p.age);
869    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
870    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
871    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
872    /// ```
873    #[inline]
874    pub fn comparing<K, F>(key_fn: F) -> Self
875    where
876        K: Ord,
877        F: Fn(&T) -> &K + 'static,
878    {
879        RcComparator::new(move |a, b| key_fn(a).cmp(key_fn(b)))
880    }
881
882    /// Converts this comparator into a closure.
883    ///
884    /// # Returns
885    ///
886    /// A closure that implements `Fn(&T, &T) -> Ordering`.
887    ///
888    /// # Examples
889    ///
890    /// ```rust
891    /// use qubit_function::comparator::{Comparator, RcComparator};
892    /// use std::cmp::Ordering;
893    ///
894    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
895    /// let func = cmp.into_fn();
896    /// assert_eq!(func(&5, &3), Ordering::Greater);
897    /// ```
898    #[inline]
899    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
900        move |a: &T, b: &T| (self.function)(a, b)
901    }
902}
903
904impl<T> Comparator<T> for RcComparator<T> {
905    #[inline]
906    fn compare(&self, a: &T, b: &T) -> Ordering {
907        (self.function)(a, b)
908    }
909}
910
911/// Extension trait providing composition methods for closures and function
912/// pointers.
913///
914/// This trait is automatically implemented for all closures and function
915/// pointers with the signature `Fn(&T, &T) -> Ordering`, allowing them to
916/// be composed directly without explicit wrapping.
917///
918/// # Examples
919///
920/// ```rust
921/// use qubit_function::comparator::{Comparator, FnComparatorOps};
922/// use std::cmp::Ordering;
923///
924/// let cmp = (|a: &i32, b: &i32| a.cmp(b))
925///     .reversed()
926///     .then_comparing(BoxComparator::new(|a, b| b.cmp(a)));
927///
928/// assert_eq!(cmp.compare(&5, &3), Ordering::Less);
929/// ```
930///
931/// # Author
932///
933/// Haixing Hu
934pub trait FnComparatorOps<T>: Fn(&T, &T) -> Ordering + Sized {
935    /// Returns a comparator that imposes the reverse ordering.
936    ///
937    /// # Returns
938    ///
939    /// A new `BoxComparator` that reverses the comparison order.
940    ///
941    /// # Examples
942    ///
943    /// ```rust
944    /// use qubit_function::comparator::{Comparator, FnComparatorOps};
945    /// use std::cmp::Ordering;
946    ///
947    /// let rev = (|a: &i32, b: &i32| a.cmp(b)).reversed();
948    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
949    /// ```
950    #[inline]
951    fn reversed(self) -> BoxComparator<T>
952    where
953        Self: 'static,
954        T: 'static,
955    {
956        BoxComparator::new(self).reversed()
957    }
958
959    /// Returns a comparator that uses this comparator first, then another
960    /// comparator if this one considers the values equal.
961    ///
962    /// # Parameters
963    ///
964    /// * `other` - The comparator to use for tie-breaking
965    ///
966    /// # Returns
967    ///
968    /// A new `BoxComparator` that chains this comparator with another.
969    ///
970    /// # Examples
971    ///
972    /// ```rust
973    /// use qubit_function::comparator::{Comparator, FnComparatorOps,
974    ///                                   BoxComparator};
975    /// use std::cmp::Ordering;
976    ///
977    /// let cmp = (|a: &i32, b: &i32| (a % 2).cmp(&(b % 2)))
978    ///     .then_comparing(BoxComparator::new(|a, b| a.cmp(b)));
979    /// assert_eq!(cmp.compare(&4, &2), Ordering::Greater);
980    /// ```
981    #[inline]
982    fn then_comparing(self, other: BoxComparator<T>) -> BoxComparator<T>
983    where
984        Self: 'static,
985        T: 'static,
986    {
987        BoxComparator::new(self).then_comparing(other)
988    }
989}
990
991impl<T, F> FnComparatorOps<T> for F where F: Fn(&T, &T) -> Ordering {}