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