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| self(first, second) && other.test(first, second))
45    }
46
47    /// Returns a bi-predicate representing logical OR with another predicate.
48    ///
49    /// This method consumes `self` and evaluates `other` only when this
50    /// closure returns `false`.
51    ///
52    /// # Parameters
53    ///
54    /// * `other` - The other bi-predicate to combine with.
55    ///
56    /// # Returns
57    ///
58    /// A `BoxStatefulBiPredicate` representing logical OR.
59    #[inline]
60    fn or<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
61    where
62        Self: 'static,
63        P: StatefulBiPredicate<T, U> + 'static,
64        T: 'static,
65        U: 'static,
66    {
67        BoxStatefulBiPredicate::new(move |first: &T, second: &U| self(first, second) || other.test(first, second))
68    }
69
70    /// Returns a bi-predicate representing logical negation.
71    ///
72    /// This method consumes `self` and returns a predicate that negates the
73    /// closure result.
74    ///
75    /// # Returns
76    ///
77    /// A `BoxStatefulBiPredicate` representing logical negation.
78    #[inline]
79    fn not(mut self) -> BoxStatefulBiPredicate<T, U>
80    where
81        Self: 'static,
82        T: 'static,
83        U: 'static,
84    {
85        BoxStatefulBiPredicate::new(move |first: &T, second: &U| !self(first, second))
86    }
87
88    /// Returns a bi-predicate representing logical NAND with another predicate.
89    ///
90    /// NAND returns `true` unless both predicates return `true`.
91    ///
92    /// # Parameters
93    ///
94    /// * `other` - The other bi-predicate to combine with.
95    ///
96    /// # Returns
97    ///
98    /// A `BoxStatefulBiPredicate` representing logical NAND.
99    #[inline]
100    fn nand<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
101    where
102        Self: 'static,
103        P: StatefulBiPredicate<T, U> + 'static,
104        T: 'static,
105        U: 'static,
106    {
107        BoxStatefulBiPredicate::new(move |first: &T, second: &U| !(self(first, second) && other.test(first, second)))
108    }
109
110    /// Returns a bi-predicate representing logical XOR with another predicate.
111    ///
112    /// XOR evaluates both predicates and returns `true` when exactly one
113    /// predicate returns `true`.
114    ///
115    /// # Parameters
116    ///
117    /// * `other` - The other bi-predicate to combine with.
118    ///
119    /// # Returns
120    ///
121    /// A `BoxStatefulBiPredicate` representing logical XOR.
122    #[inline]
123    fn xor<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
124    where
125        Self: 'static,
126        P: StatefulBiPredicate<T, U> + 'static,
127        T: 'static,
128        U: 'static,
129    {
130        BoxStatefulBiPredicate::new(move |first: &T, second: &U| self(first, second) ^ other.test(first, second))
131    }
132
133    /// Returns a bi-predicate representing logical NOR with another predicate.
134    ///
135    /// NOR returns `true` only when both predicates return `false`.
136    ///
137    /// # Parameters
138    ///
139    /// * `other` - The other bi-predicate to combine with.
140    ///
141    /// # Returns
142    ///
143    /// A `BoxStatefulBiPredicate` representing logical NOR.
144    #[inline]
145    fn nor<P>(mut self, mut other: P) -> BoxStatefulBiPredicate<T, U>
146    where
147        Self: 'static,
148        P: StatefulBiPredicate<T, U> + 'static,
149        T: 'static,
150        U: 'static,
151    {
152        BoxStatefulBiPredicate::new(move |first: &T, second: &U| !(self(first, second) || other.test(first, second)))
153    }
154}
155
156impl<T, U, F> FnStatefulBiPredicateOps<T, U> for F where F: FnMut(&T, &U) -> bool {}