Skip to main content

qubit_function/predicates/stateful_bi_predicate/
fn_stateful_bi_predicate_ops.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10// qubit-style: allow explicit-imports
11//! Defines the `FnStatefulBiPredicateOps` public type.
12
13use super::{
14    BoxStatefulBiPredicate,
15    StatefulBiPredicate,
16};
17
18/// Extension trait providing logical composition methods for stateful closures.
19///
20/// This trait is implemented for closures and function objects matching
21/// `FnMut(&T, &U) -> bool`, allowing direct composition into
22/// `BoxStatefulBiPredicate`.
23pub trait FnStatefulBiPredicateOps<T, U>: FnMut(&T, &U) -> bool + Sized {
24    /// Returns a bi-predicate representing logical AND with another predicate.
25    ///
26    /// This method consumes `self` and evaluates `other` only when this
27    /// closure returns `true`.
28    ///
29    /// # Parameters
30    ///
31    /// * `other` - The other bi-predicate to combine with.
32    ///
33    /// # Returns
34    ///
35    /// A `BoxStatefulBiPredicate` representing logical AND.
36    #[inline]
37    fn and<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
38    where
39        Self: 'static,
40        P: StatefulBiPredicate<T, U> + 'static,
41        T: 'static,
42        U: 'static,
43    {
44        BoxStatefulBiPredicate::new(move |first: &T, second: &U| {
45            self(first, second) && other.test(first, second)
46        })
47    }
48
49    /// Returns a bi-predicate representing logical OR with another predicate.
50    ///
51    /// This method consumes `self` and evaluates `other` only when this
52    /// closure returns `false`.
53    ///
54    /// # Parameters
55    ///
56    /// * `other` - The other bi-predicate to combine with.
57    ///
58    /// # Returns
59    ///
60    /// A `BoxStatefulBiPredicate` representing logical OR.
61    #[inline]
62    fn or<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
63    where
64        Self: 'static,
65        P: StatefulBiPredicate<T, U> + 'static,
66        T: 'static,
67        U: 'static,
68    {
69        BoxStatefulBiPredicate::new(move |first: &T, second: &U| {
70            self(first, second) || other.test(first, second)
71        })
72    }
73
74    /// Returns a bi-predicate representing logical negation.
75    ///
76    /// This method consumes `self` and returns a predicate that negates the
77    /// closure result.
78    ///
79    /// # Returns
80    ///
81    /// A `BoxStatefulBiPredicate` representing logical negation.
82    #[inline]
83    fn not(mut self) -> BoxStatefulBiPredicate<T, U>
84    where
85        Self: 'static,
86        T: 'static,
87        U: 'static,
88    {
89        BoxStatefulBiPredicate::new(move |first: &T, second: &U| !self(first, second))
90    }
91
92    /// Returns a bi-predicate representing logical NAND with another predicate.
93    ///
94    /// NAND returns `true` unless both predicates return `true`.
95    ///
96    /// # Parameters
97    ///
98    /// * `other` - The other bi-predicate to combine with.
99    ///
100    /// # Returns
101    ///
102    /// A `BoxStatefulBiPredicate` representing logical NAND.
103    #[inline]
104    fn nand<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
105    where
106        Self: 'static,
107        P: StatefulBiPredicate<T, U> + 'static,
108        T: 'static,
109        U: 'static,
110    {
111        BoxStatefulBiPredicate::new(move |first: &T, second: &U| {
112            !(self(first, second) && other.test(first, second))
113        })
114    }
115
116    /// Returns a bi-predicate representing logical XOR with another predicate.
117    ///
118    /// XOR evaluates both predicates and returns `true` when exactly one
119    /// predicate returns `true`.
120    ///
121    /// # Parameters
122    ///
123    /// * `other` - The other bi-predicate to combine with.
124    ///
125    /// # Returns
126    ///
127    /// A `BoxStatefulBiPredicate` representing logical XOR.
128    #[inline]
129    fn xor<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
130    where
131        Self: 'static,
132        P: StatefulBiPredicate<T, U> + 'static,
133        T: 'static,
134        U: 'static,
135    {
136        BoxStatefulBiPredicate::new(move |first: &T, second: &U| {
137            self(first, second) ^ other.test(first, second)
138        })
139    }
140
141    /// Returns a bi-predicate representing logical NOR with another predicate.
142    ///
143    /// NOR returns `true` only when both predicates return `false`.
144    ///
145    /// # Parameters
146    ///
147    /// * `other` - The other bi-predicate to combine with.
148    ///
149    /// # Returns
150    ///
151    /// A `BoxStatefulBiPredicate` representing logical NOR.
152    #[inline]
153    fn nor<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
154    where
155        Self: 'static,
156        P: StatefulBiPredicate<T, U> + 'static,
157        T: 'static,
158        U: 'static,
159    {
160        BoxStatefulBiPredicate::new(move |first: &T, second: &U| {
161            !(self(first, second) || other.test(first, second))
162        })
163    }
164}
165
166impl<T, U, F> FnStatefulBiPredicateOps<T, U> for F where F: FnMut(&T, &U) -> bool {}