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    {
249        BoxComparator::new(move |a, b| self.compare(a, b))
250    }
251
252    /// Converts this comparator into an `ArcComparator`.
253    ///
254    /// # Returns
255    ///
256    /// A new `ArcComparator` wrapping this comparator.
257    ///
258    /// # Examples
259    ///
260    /// ```rust
261    /// use qubit_function::comparator::{Comparator, ArcComparator};
262    ///
263    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
264    /// let arc = cmp.into_arc();
265    /// ```
266    #[inline]
267    fn into_arc(self) -> ArcComparator<T>
268    where
269        Self: Sized + Send + Sync + 'static,
270    {
271        ArcComparator::new(move |a, b| self.compare(a, b))
272    }
273
274    /// Converts this comparator into an `RcComparator`.
275    ///
276    /// # Returns
277    ///
278    /// A new `RcComparator` wrapping this comparator.
279    ///
280    /// # Examples
281    ///
282    /// ```rust
283    /// use qubit_function::comparator::{Comparator, RcComparator};
284    ///
285    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
286    /// let rc = cmp.into_rc();
287    /// ```
288    #[inline]
289    fn into_rc(self) -> RcComparator<T>
290    where
291        Self: Sized + 'static,
292    {
293        RcComparator::new(move |a, b| self.compare(a, b))
294    }
295
296    /// Converts this comparator into a closure that implements
297    /// `Fn(&T, &T) -> Ordering`.
298    ///
299    /// This method consumes the comparator and returns a closure that
300    /// can be used anywhere a function or closure is expected.
301    ///
302    /// # Returns
303    ///
304    /// An implementation that can be called as `Fn(&T, &T) -> Ordering`.
305    ///
306    /// # Examples
307    ///
308    /// ```rust
309    /// use qubit_function::comparator::{Comparator, BoxComparator};
310    /// use std::cmp::Ordering;
311    ///
312    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
313    /// let func = cmp.into_fn();
314    /// assert_eq!(func(&5, &3), Ordering::Greater);
315    /// ```
316    #[inline]
317    fn into_fn(self) -> impl Fn(&T, &T) -> Ordering
318    where
319        Self: Sized + 'static,
320    {
321        move |a: &T, b: &T| self.compare(a, b)
322    }
323}
324
325/// Blanket implementation of `Comparator` for all closures and function
326/// pointers.
327///
328/// This allows any closure or function with the signature
329/// `Fn(&T, &T) -> Ordering` to be used as a comparator.
330///
331/// # Examples
332///
333/// ```rust
334/// use qubit_function::comparator::Comparator;
335/// use std::cmp::Ordering;
336///
337/// let cmp = |a: &i32, b: &i32| a.cmp(b);
338/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
339/// ```
340impl<T, F> Comparator<T> for F
341where
342    F: Fn(&T, &T) -> Ordering,
343{
344    #[inline]
345    fn compare(&self, a: &T, b: &T) -> Ordering {
346        self(a, b)
347    }
348}
349
350/// A boxed comparator with single ownership.
351///
352/// `BoxComparator` wraps a comparator function in a `Box`, providing single
353/// ownership semantics. It is not cloneable and consumes `self` in
354/// composition operations.
355///
356/// # Type Parameters
357///
358/// * `T` - The type of values being compared
359///
360/// # Examples
361///
362/// ```rust
363/// use qubit_function::comparator::{Comparator, BoxComparator};
364/// use std::cmp::Ordering;
365///
366/// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
367/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
368/// ```
369///
370/// # Author
371///
372/// Haixing Hu
373pub struct BoxComparator<T> {
374    function: Box<dyn Fn(&T, &T) -> Ordering>,
375}
376
377impl<T> BoxComparator<T> {
378    /// Creates a new `BoxComparator` from a closure.
379    ///
380    /// # Parameters
381    ///
382    /// * `f` - The closure to wrap
383    ///
384    /// # Returns
385    ///
386    /// A new `BoxComparator` instance.
387    ///
388    /// # Examples
389    ///
390    /// ```rust
391    /// use qubit_function::comparator::BoxComparator;
392    ///
393    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
394    /// ```
395    #[inline]
396    pub fn new<F>(f: F) -> Self
397    where
398        F: Fn(&T, &T) -> Ordering + 'static,
399    {
400        Self {
401            function: Box::new(f),
402        }
403    }
404
405    /// Returns a comparator that imposes the reverse ordering.
406    ///
407    /// # Returns
408    ///
409    /// A new `BoxComparator` that reverses the comparison order.
410    ///
411    /// # Examples
412    ///
413    /// ```rust
414    /// use qubit_function::comparator::{Comparator, BoxComparator};
415    /// use std::cmp::Ordering;
416    ///
417    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
418    /// let rev = cmp.reversed();
419    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
420    /// ```
421    #[inline]
422    pub fn reversed(self) -> Self
423    where
424        T: 'static,
425    {
426        BoxComparator::new(move |a, b| (self.function)(b, a))
427    }
428
429    /// Returns a comparator that uses this comparator first, then another
430    /// comparator if this one considers the values equal.
431    ///
432    /// # Parameters
433    ///
434    /// * `other` - The comparator to use for tie-breaking. **Note: This
435    ///   parameter is passed by value and will transfer ownership.** If you
436    ///   need to preserve the original comparator, clone it first (if it
437    ///   implements `Clone`). Can be:
438    ///   - A `BoxComparator<T>`
439    ///   - An `RcComparator<T>`
440    ///   - An `ArcComparator<T>`
441    ///   - Any type implementing `Comparator<T>`
442    ///
443    /// # Returns
444    ///
445    /// A new `BoxComparator` that chains this comparator with another.
446    ///
447    /// # Examples
448    ///
449    /// ```rust
450    /// use qubit_function::comparator::{Comparator, BoxComparator};
451    /// use std::cmp::Ordering;
452    ///
453    /// #[derive(Debug)]
454    /// struct Person {
455    ///     name: String,
456    ///     age: i32,
457    /// }
458    ///
459    /// let by_name = BoxComparator::new(|a: &Person, b: &Person| {
460    ///     a.name.cmp(&b.name)
461    /// });
462    /// let by_age = BoxComparator::new(|a: &Person, b: &Person| {
463    ///     a.age.cmp(&b.age)
464    /// });
465    ///
466    /// // by_age is moved here
467    /// let cmp = by_name.then_comparing(by_age);
468    ///
469    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
470    /// let p2 = Person { name: "Alice".to_string(), age: 25 };
471    /// assert_eq!(cmp.compare(&p1, &p2), Ordering::Greater);
472    /// // by_age.compare(&p1, &p2); // Would not compile - moved
473    /// ```
474    #[inline]
475    pub fn then_comparing(self, other: Self) -> Self
476    where
477        T: 'static,
478    {
479        BoxComparator::new(move |a, b| match (self.function)(a, b) {
480            Ordering::Equal => (other.function)(a, b),
481            ord => ord,
482        })
483    }
484
485    /// Returns a comparator that compares values by a key extracted by the
486    /// given function.
487    ///
488    /// # Parameters
489    ///
490    /// * `key_fn` - A function that extracts a comparable key from values
491    ///
492    /// # Returns
493    ///
494    /// A new `BoxComparator` that compares by the extracted key.
495    ///
496    /// # Examples
497    ///
498    /// ```rust
499    /// use qubit_function::comparator::{Comparator, BoxComparator};
500    /// use std::cmp::Ordering;
501    ///
502    /// #[derive(Debug)]
503    /// struct Person {
504    ///     name: String,
505    ///     age: i32,
506    /// }
507    ///
508    /// let by_age = BoxComparator::comparing(|p: &Person| &p.age);
509    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
510    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
511    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
512    /// ```
513    #[inline]
514    pub fn comparing<K, F>(key_fn: F) -> Self
515    where
516        K: Ord,
517        F: Fn(&T) -> &K + 'static,
518    {
519        BoxComparator::new(move |a: &T, b: &T| key_fn(a).cmp(key_fn(b)))
520    }
521
522    /// Converts this comparator into a closure.
523    ///
524    /// # Returns
525    ///
526    /// A closure that implements `Fn(&T, &T) -> Ordering`.
527    ///
528    /// # Examples
529    ///
530    /// ```rust
531    /// use qubit_function::comparator::{Comparator, BoxComparator};
532    /// use std::cmp::Ordering;
533    ///
534    /// let cmp = BoxComparator::new(|a: &i32, b: &i32| a.cmp(b));
535    /// let func = cmp.into_fn();
536    /// assert_eq!(func(&5, &3), Ordering::Greater);
537    /// ```
538    #[inline]
539    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
540        move |a: &T, b: &T| (self.function)(a, b)
541    }
542}
543
544impl<T> Comparator<T> for BoxComparator<T> {
545    #[inline]
546    fn compare(&self, a: &T, b: &T) -> Ordering {
547        (self.function)(a, b)
548    }
549}
550
551/// An Arc-based thread-safe comparator with shared ownership.
552///
553/// `ArcComparator` wraps a comparator function in an `Arc`, providing
554/// thread-safe shared ownership semantics. It is cloneable and uses `&self`
555/// in composition operations.
556///
557/// # Type Parameters
558///
559/// * `T` - The type of values being compared
560///
561/// # Examples
562///
563/// ```rust
564/// use qubit_function::comparator::{Comparator, ArcComparator};
565/// use std::cmp::Ordering;
566///
567/// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
568/// let cloned = cmp.clone();
569/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
570/// assert_eq!(cloned.compare(&5, &3), Ordering::Greater);
571/// ```
572///
573/// # Author
574///
575/// Haixing Hu
576#[derive(Clone)]
577pub struct ArcComparator<T> {
578    function: Arc<dyn Fn(&T, &T) -> Ordering + Send + Sync>,
579}
580
581impl<T> ArcComparator<T> {
582    /// Creates a new `ArcComparator` from a closure.
583    ///
584    /// # Parameters
585    ///
586    /// * `f` - The closure to wrap
587    ///
588    /// # Returns
589    ///
590    /// A new `ArcComparator` instance.
591    ///
592    /// # Examples
593    ///
594    /// ```rust
595    /// use qubit_function::comparator::ArcComparator;
596    ///
597    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
598    /// ```
599    #[inline]
600    pub fn new<F>(f: F) -> Self
601    where
602        F: Fn(&T, &T) -> Ordering + Send + Sync + 'static,
603    {
604        Self {
605            function: Arc::new(f),
606        }
607    }
608
609    /// Returns a comparator that imposes the reverse ordering.
610    ///
611    /// # Returns
612    ///
613    /// A new `ArcComparator` that reverses the comparison order.
614    ///
615    /// # Examples
616    ///
617    /// ```rust
618    /// use qubit_function::comparator::{Comparator, ArcComparator};
619    /// use std::cmp::Ordering;
620    ///
621    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
622    /// let rev = cmp.reversed();
623    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
624    /// assert_eq!(cmp.compare(&5, &3), Ordering::Greater); // cmp still works
625    /// ```
626    #[inline]
627    pub fn reversed(&self) -> Self
628    where
629        T: 'static,
630    {
631        let self_fn = self.function.clone();
632        ArcComparator::new(move |a, b| self_fn(b, a))
633    }
634
635    /// Returns a comparator that uses this comparator first, then another
636    /// comparator if this one considers the values equal.
637    ///
638    /// # Parameters
639    ///
640    /// * `other` - The comparator to use for tie-breaking
641    ///
642    /// # Returns
643    ///
644    /// A new `ArcComparator` that chains this comparator with another.
645    ///
646    /// # Examples
647    ///
648    /// ```rust
649    /// use qubit_function::comparator::{Comparator, ArcComparator};
650    /// use std::cmp::Ordering;
651    ///
652    /// let cmp1 = ArcComparator::new(|a: &i32, b: &i32| {
653    ///     (a % 2).cmp(&(b % 2))
654    /// });
655    /// let cmp2 = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
656    /// let chained = cmp1.then_comparing(&cmp2);
657    /// assert_eq!(chained.compare(&4, &2), Ordering::Greater);
658    /// ```
659    #[inline]
660    pub fn then_comparing(&self, other: &Self) -> Self
661    where
662        T: 'static,
663    {
664        let first = self.function.clone();
665        let second = other.function.clone();
666        ArcComparator::new(move |a, b| match first(a, b) {
667            Ordering::Equal => second(a, b),
668            ord => ord,
669        })
670    }
671
672    /// Returns a comparator that compares values by a key extracted by the
673    /// given function.
674    ///
675    /// # Parameters
676    ///
677    /// * `key_fn` - A function that extracts a comparable key from values
678    ///
679    /// # Returns
680    ///
681    /// A new `ArcComparator` that compares by the extracted key.
682    ///
683    /// # Examples
684    ///
685    /// ```rust
686    /// use qubit_function::comparator::{Comparator, ArcComparator};
687    /// use std::cmp::Ordering;
688    ///
689    /// #[derive(Debug)]
690    /// struct Person {
691    ///     name: String,
692    ///     age: i32,
693    /// }
694    ///
695    /// let by_age = ArcComparator::comparing(|p: &Person| &p.age);
696    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
697    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
698    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
699    /// ```
700    #[inline]
701    pub fn comparing<K, F>(key_fn: F) -> Self
702    where
703        K: Ord,
704        F: Fn(&T) -> &K + Send + Sync + 'static,
705    {
706        ArcComparator::new(move |a, b| key_fn(a).cmp(key_fn(b)))
707    }
708
709    /// Converts this comparator into a closure.
710    ///
711    /// # Returns
712    ///
713    /// A closure that implements `Fn(&T, &T) -> Ordering`.
714    ///
715    /// # Examples
716    ///
717    /// ```rust
718    /// use qubit_function::comparator::{Comparator, ArcComparator};
719    /// use std::cmp::Ordering;
720    ///
721    /// let cmp = ArcComparator::new(|a: &i32, b: &i32| a.cmp(b));
722    /// let func = cmp.into_fn();
723    /// assert_eq!(func(&5, &3), Ordering::Greater);
724    /// ```
725    #[inline]
726    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
727        move |a: &T, b: &T| (self.function)(a, b)
728    }
729}
730
731impl<T> Comparator<T> for ArcComparator<T> {
732    #[inline]
733    fn compare(&self, a: &T, b: &T) -> Ordering {
734        (self.function)(a, b)
735    }
736}
737
738/// An Rc-based single-threaded comparator with shared ownership.
739///
740/// `RcComparator` wraps a comparator function in an `Rc`, providing
741/// single-threaded shared ownership semantics. It is cloneable and uses
742/// `&self` in composition operations.
743///
744/// # Type Parameters
745///
746/// * `T` - The type of values being compared
747///
748/// # Examples
749///
750/// ```rust
751/// use qubit_function::comparator::{Comparator, RcComparator};
752/// use std::cmp::Ordering;
753///
754/// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
755/// let cloned = cmp.clone();
756/// assert_eq!(cmp.compare(&5, &3), Ordering::Greater);
757/// assert_eq!(cloned.compare(&5, &3), Ordering::Greater);
758/// ```
759///
760/// # Author
761///
762/// Haixing Hu
763#[derive(Clone)]
764pub struct RcComparator<T> {
765    function: Rc<dyn Fn(&T, &T) -> Ordering>,
766}
767
768impl<T> RcComparator<T> {
769    /// Creates a new `RcComparator` from a closure.
770    ///
771    /// # Parameters
772    ///
773    /// * `f` - The closure to wrap
774    ///
775    /// # Returns
776    ///
777    /// A new `RcComparator` instance.
778    ///
779    /// # Examples
780    ///
781    /// ```rust
782    /// use qubit_function::comparator::RcComparator;
783    ///
784    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
785    /// ```
786    #[inline]
787    pub fn new<F>(f: F) -> Self
788    where
789        F: Fn(&T, &T) -> Ordering + 'static,
790    {
791        Self {
792            function: Rc::new(f),
793        }
794    }
795
796    /// Returns a comparator that imposes the reverse ordering.
797    ///
798    /// # Returns
799    ///
800    /// A new `RcComparator` that reverses the comparison order.
801    ///
802    /// # Examples
803    ///
804    /// ```rust
805    /// use qubit_function::comparator::{Comparator, RcComparator};
806    /// use std::cmp::Ordering;
807    ///
808    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
809    /// let rev = cmp.reversed();
810    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
811    /// assert_eq!(cmp.compare(&5, &3), Ordering::Greater); // cmp still works
812    /// ```
813    #[inline]
814    pub fn reversed(&self) -> Self
815    where
816        T: 'static,
817    {
818        let self_fn = self.function.clone();
819        RcComparator::new(move |a, b| self_fn(b, a))
820    }
821
822    /// Returns a comparator that uses this comparator first, then another
823    /// comparator if this one considers the values equal.
824    ///
825    /// # Parameters
826    ///
827    /// * `other` - The comparator to use for tie-breaking
828    ///
829    /// # Returns
830    ///
831    /// A new `RcComparator` that chains this comparator with another.
832    ///
833    /// # Examples
834    ///
835    /// ```rust
836    /// use qubit_function::comparator::{Comparator, RcComparator};
837    /// use std::cmp::Ordering;
838    ///
839    /// let cmp1 = RcComparator::new(|a: &i32, b: &i32| {
840    ///     (a % 2).cmp(&(b % 2))
841    /// });
842    /// let cmp2 = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
843    /// let chained = cmp1.then_comparing(&cmp2);
844    /// assert_eq!(chained.compare(&4, &2), Ordering::Greater);
845    /// ```
846    #[inline]
847    pub fn then_comparing(&self, other: &Self) -> Self
848    where
849        T: 'static,
850    {
851        let first = self.function.clone();
852        let second = other.function.clone();
853        RcComparator::new(move |a, b| match first(a, b) {
854            Ordering::Equal => second(a, b),
855            ord => ord,
856        })
857    }
858
859    /// Returns a comparator that compares values by a key extracted by the
860    /// given function.
861    ///
862    /// # Parameters
863    ///
864    /// * `key_fn` - A function that extracts a comparable key from values
865    ///
866    /// # Returns
867    ///
868    /// A new `RcComparator` that compares by the extracted key.
869    ///
870    /// # Examples
871    ///
872    /// ```rust
873    /// use qubit_function::comparator::{Comparator, RcComparator};
874    /// use std::cmp::Ordering;
875    ///
876    /// #[derive(Debug)]
877    /// struct Person {
878    ///     name: String,
879    ///     age: i32,
880    /// }
881    ///
882    /// let by_age = RcComparator::comparing(|p: &Person| &p.age);
883    /// let p1 = Person { name: "Alice".to_string(), age: 30 };
884    /// let p2 = Person { name: "Bob".to_string(), age: 25 };
885    /// assert_eq!(by_age.compare(&p1, &p2), Ordering::Greater);
886    /// ```
887    #[inline]
888    pub fn comparing<K, F>(key_fn: F) -> Self
889    where
890        K: Ord,
891        F: Fn(&T) -> &K + 'static,
892    {
893        RcComparator::new(move |a, b| key_fn(a).cmp(key_fn(b)))
894    }
895
896    /// Converts this comparator into a closure.
897    ///
898    /// # Returns
899    ///
900    /// A closure that implements `Fn(&T, &T) -> Ordering`.
901    ///
902    /// # Examples
903    ///
904    /// ```rust
905    /// use qubit_function::comparator::{Comparator, RcComparator};
906    /// use std::cmp::Ordering;
907    ///
908    /// let cmp = RcComparator::new(|a: &i32, b: &i32| a.cmp(b));
909    /// let func = cmp.into_fn();
910    /// assert_eq!(func(&5, &3), Ordering::Greater);
911    /// ```
912    #[inline]
913    pub fn into_fn(self) -> impl Fn(&T, &T) -> Ordering {
914        move |a: &T, b: &T| (self.function)(a, b)
915    }
916}
917
918impl<T> Comparator<T> for RcComparator<T> {
919    #[inline]
920    fn compare(&self, a: &T, b: &T) -> Ordering {
921        (self.function)(a, b)
922    }
923}
924
925/// Extension trait providing composition methods for closures and function
926/// pointers.
927///
928/// This trait is automatically implemented for all closures and function
929/// pointers with the signature `Fn(&T, &T) -> Ordering`, allowing them to
930/// be composed directly without explicit wrapping.
931///
932/// # Examples
933///
934/// ```rust
935/// use qubit_function::comparator::{Comparator, FnComparatorOps};
936/// use std::cmp::Ordering;
937///
938/// let cmp = (|a: &i32, b: &i32| a.cmp(b))
939///     .reversed()
940///     .then_comparing(BoxComparator::new(|a, b| b.cmp(a)));
941///
942/// assert_eq!(cmp.compare(&5, &3), Ordering::Less);
943/// ```
944///
945/// # Author
946///
947/// Haixing Hu
948pub trait FnComparatorOps<T>: Fn(&T, &T) -> Ordering + Sized {
949    /// Returns a comparator that imposes the reverse ordering.
950    ///
951    /// # Returns
952    ///
953    /// A new `BoxComparator` that reverses the comparison order.
954    ///
955    /// # Examples
956    ///
957    /// ```rust
958    /// use qubit_function::comparator::{Comparator, FnComparatorOps};
959    /// use std::cmp::Ordering;
960    ///
961    /// let rev = (|a: &i32, b: &i32| a.cmp(b)).reversed();
962    /// assert_eq!(rev.compare(&5, &3), Ordering::Less);
963    /// ```
964    #[inline]
965    fn reversed(self) -> BoxComparator<T>
966    where
967        Self: 'static,
968        T: 'static,
969    {
970        BoxComparator::new(self).reversed()
971    }
972
973    /// Returns a comparator that uses this comparator first, then another
974    /// comparator if this one considers the values equal.
975    ///
976    /// # Parameters
977    ///
978    /// * `other` - The comparator to use for tie-breaking
979    ///
980    /// # Returns
981    ///
982    /// A new `BoxComparator` that chains this comparator with another.
983    ///
984    /// # Examples
985    ///
986    /// ```rust
987    /// use qubit_function::comparator::{Comparator, FnComparatorOps,
988    ///                                   BoxComparator};
989    /// use std::cmp::Ordering;
990    ///
991    /// let cmp = (|a: &i32, b: &i32| (a % 2).cmp(&(b % 2)))
992    ///     .then_comparing(BoxComparator::new(|a, b| a.cmp(b)));
993    /// assert_eq!(cmp.compare(&4, &2), Ordering::Greater);
994    /// ```
995    #[inline]
996    fn then_comparing(self, other: BoxComparator<T>) -> BoxComparator<T>
997    where
998        Self: 'static,
999        T: 'static,
1000    {
1001        BoxComparator::new(self).then_comparing(other)
1002    }
1003}
1004
1005impl<T, F> FnComparatorOps<T> for F where F: Fn(&T, &T) -> Ordering {}