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 {}