qubit_function/functions/stateful_function.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # StatefulFunction Types
10//!
11//! Provides Rust implementations of stateful function traits for stateful value
12//! transformation. StatefulFunctions consume input values (taking ownership) and
13//! produce output values while allowing internal state modification.
14//!
15//! It is similar to the `FnMut(&T) -> R` trait in the standard library.
16//!
17//! This module provides the `StatefulFunction<T, R>` trait and three implementations:
18//!
19//! - [`BoxStatefulFunction`]: Single ownership, not cloneable
20//! - [`ArcStatefulFunction`]: Thread-safe shared ownership, cloneable
21//! - [`RcStatefulFunction`]: Single-threaded shared ownership, cloneable
22//!
23//! # Author
24//!
25//! Haixing Hu
26use std::cell::RefCell;
27use std::rc::Rc;
28use std::sync::Arc;
29
30use parking_lot::Mutex;
31
32use crate::functions::{
33 function_once::BoxFunctionOnce,
34 macros::{
35 impl_box_conditional_function,
36 impl_box_function_methods,
37 impl_conditional_function_clone,
38 impl_conditional_function_debug_display,
39 impl_fn_ops_trait,
40 impl_function_clone,
41 impl_function_common_methods,
42 impl_function_constant_method,
43 impl_function_debug_display,
44 impl_function_identity_method,
45 impl_shared_conditional_function,
46 impl_shared_function_methods,
47 },
48};
49use crate::macros::{
50 impl_arc_conversions,
51 impl_box_conversions,
52 impl_rc_conversions,
53};
54use crate::predicates::predicate::{
55 ArcPredicate,
56 BoxPredicate,
57 Predicate,
58 RcPredicate,
59};
60
61// ============================================================================
62// Core Trait
63// ============================================================================
64
65/// StatefulFunction trait - transforms values from type T to type R with state
66///
67/// Defines the behavior of a stateful transformation: converting a value
68/// of type `T` to a value of type `R` by consuming the input while
69/// allowing modification of internal state. This is analogous to
70/// `FnMut(&T) -> R` in Rust's standard library.
71///
72/// # Type Parameters
73///
74/// * `T` - The type of the input value (consumed)
75/// * `R` - The type of the output value
76///
77/// # Author
78///
79/// Haixing Hu
80pub trait StatefulFunction<T, R> {
81 /// Applies the mapping to the input value to produce an output value
82 ///
83 /// # Parameters
84 ///
85 /// * `t` - The input value to transform (consumed)
86 ///
87 /// # Returns
88 ///
89 /// The transformed output value
90 fn apply(&mut self, t: &T) -> R;
91
92 /// Converts to BoxStatefulFunction
93 ///
94 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
95 /// after calling this method.
96 ///
97 /// # Returns
98 ///
99 /// Returns `BoxStatefulFunction<T, R>`
100 ///
101 /// # Default Implementation
102 ///
103 /// The default implementation wraps `self` in a `BoxStatefulFunction` by creating
104 /// a new closure that calls `self.apply()`. This provides a zero-cost
105 /// abstraction for most use cases.
106 ///
107 /// # Examples
108 ///
109 /// ```rust
110 /// use qubit_function::{StatefulFunction, BoxStatefulFunction};
111 ///
112 /// struct CustomStatefulFunction {
113 /// multiplier: i32,
114 /// }
115 ///
116 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
117 /// fn apply(&mut self, input: i32) -> i32 {
118 /// self.multiplier += 1;
119 /// input * self.multiplier
120 /// }
121 /// }
122 ///
123 /// let function = CustomStatefulFunction { multiplier: 0 };
124 /// let mut boxed = function.into_box();
125 /// assert_eq!(boxed.apply(10), 10); // 10 * 1
126 /// assert_eq!(boxed.apply(10), 20); // 10 * 2
127 /// ```
128 fn into_box(mut self) -> BoxStatefulFunction<T, R>
129 where
130 Self: Sized + 'static,
131 T: 'static,
132 R: 'static,
133 {
134 BoxStatefulFunction::new(move |t| self.apply(t))
135 }
136
137 /// Converts to RcStatefulFunction
138 ///
139 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
140 /// after calling this method.
141 ///
142 /// # Returns
143 ///
144 /// Returns `RcStatefulFunction<T, R>`
145 ///
146 /// # Default Implementation
147 ///
148 /// The default implementation first converts to `BoxStatefulFunction` using
149 /// `into_box()`, then wraps it in `RcStatefulFunction`. Specific implementations
150 /// may override this for better efficiency.
151 ///
152 /// # Examples
153 ///
154 /// ```rust
155 /// use qubit_function::{StatefulFunction, RcStatefulFunction};
156 ///
157 /// struct CustomStatefulFunction {
158 /// multiplier: i32,
159 /// }
160 ///
161 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
162 /// fn apply(&mut self, input: i32) -> i32 {
163 /// self.multiplier += 1;
164 /// input * self.multiplier
165 /// }
166 /// }
167 ///
168 /// let function = CustomStatefulFunction { multiplier: 0 };
169 /// let mut rc_function = function.into_rc();
170 /// assert_eq!(rc_function.apply(10), 10); // 10 * 1
171 /// assert_eq!(rc_function.apply(10), 20); // 10 * 2
172 /// ```
173 fn into_rc(mut self) -> RcStatefulFunction<T, R>
174 where
175 Self: Sized + 'static,
176 T: 'static,
177 R: 'static,
178 {
179 RcStatefulFunction::new(move |t| self.apply(t))
180 }
181
182 /// Converts to ArcStatefulFunction
183 ///
184 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
185 /// after calling this method.
186 ///
187 /// # Returns
188 ///
189 /// Returns `ArcStatefulFunction<T, R>`
190 ///
191 /// # Default Implementation
192 ///
193 /// The default implementation wraps `self` in an `ArcStatefulFunction` by creating
194 /// a new closure that calls `self.apply()`. Note that this requires `self`
195 /// to implement `Send` due to Arc's thread-safety requirements.
196 ///
197 /// # Examples
198 ///
199 /// ```rust
200 /// use qubit_function::{StatefulFunction, ArcStatefulFunction};
201 ///
202 /// struct CustomStatefulFunction {
203 /// multiplier: i32,
204 /// }
205 ///
206 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
207 /// fn apply(&mut self, input: i32) -> i32 {
208 /// self.multiplier += 1;
209 /// input * self.multiplier
210 /// }
211 /// }
212 ///
213 /// let function = CustomStatefulFunction { multiplier: 0 };
214 /// let mut arc_function = function.into_arc();
215 /// assert_eq!(arc_function.apply(10), 10); // 10 * 1
216 /// assert_eq!(arc_function.apply(10), 20); // 10 * 2
217 /// ```
218 fn into_arc(mut self) -> ArcStatefulFunction<T, R>
219 where
220 Self: Sized + Send + Sync + 'static,
221 T: Send + Sync + 'static,
222 R: 'static,
223 {
224 ArcStatefulFunction::new(move |t| self.apply(t))
225 }
226
227 /// Converts to a closure implementing `FnMut(&T) -> R`
228 ///
229 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
230 /// after calling this method.
231 ///
232 /// # Returns
233 ///
234 /// Returns an implementation of `FnMut(&T) -> R`
235 ///
236 /// # Default Implementation
237 ///
238 /// The default implementation creates a new closure that calls `self.apply()`.
239 /// Specific implementations may override this for better efficiency.
240 ///
241 /// # Examples
242 ///
243 /// ```rust
244 /// use qubit_function::{StatefulFunction, BoxStatefulFunction};
245 ///
246 /// let function = BoxStatefulFunction::new(|x: i32| x * 2);
247 /// let mut closure = function.into_fn();
248 /// assert_eq!(closure(10), 20);
249 /// assert_eq!(closure(15), 30);
250 /// ```
251 fn into_fn(mut self) -> impl FnMut(&T) -> R
252 where
253 Self: Sized + 'static,
254 {
255 move |t| self.apply(t)
256 }
257
258 /// Convert to StatefulFunctionOnce
259 ///
260 /// **⚠️ Consumes `self`**: The original function will be unavailable
261 /// after calling this method.
262 ///
263 /// Converts a reusable stateful function to a one-time function that
264 /// consumes itself on use. This enables passing `StatefulFunction` to
265 /// functions that require `StatefulFunctionOnce`.
266 ///
267 /// # Returns
268 ///
269 /// Returns a `BoxFunctionOnce<T, R>`
270 ///
271 /// # Examples
272 ///
273 /// ```rust
274 /// use qubit_function::{StatefulFunctionOnce, StatefulFunction,
275 /// BoxStatefulFunction};
276 ///
277 /// fn takes_once<F: StatefulFunctionOnce<i32, i32>>(func: F, value: &i32) {
278 /// let result = func.apply(value);
279 /// println!("Result: {}", result);
280 /// }
281 ///
282 /// let func = BoxStatefulFunction::new(|x: &i32| x * 2);
283 /// takes_once(func.into_once(), &5);
284 /// ```
285 fn into_once(mut self) -> BoxFunctionOnce<T, R>
286 where
287 Self: Sized + 'static,
288 T: 'static,
289 R: 'static,
290 {
291 BoxFunctionOnce::new(move |t| self.apply(t))
292 }
293
294 /// Non-consuming conversion to `BoxStatefulFunction`.
295 ///
296 /// Default implementation requires `Self: Clone` and wraps a cloned
297 /// instance in a `RefCell` so the returned stateful function can mutate state
298 /// across calls.
299 fn to_box(&self) -> BoxStatefulFunction<T, R>
300 where
301 Self: Clone + 'static,
302 T: 'static,
303 R: 'static,
304 {
305 self.clone().into_box()
306 }
307
308 /// Non-consuming conversion to `RcStatefulFunction`.
309 ///
310 /// Default implementation clones `self` into an `Rc<RefCell<_>>` so the
311 /// resulting stateful function can be shared within a single thread.
312 fn to_rc(&self) -> RcStatefulFunction<T, R>
313 where
314 Self: Clone + 'static,
315 T: 'static,
316 R: 'static,
317 {
318 self.clone().into_rc()
319 }
320
321 /// Non-consuming conversion to `ArcStatefulFunction` (thread-safe).
322 ///
323 /// Default implementation requires `Self: Clone + Send + Sync` and wraps
324 /// the cloned instance in `Arc<Mutex<_>>` so it can be used across
325 /// threads.
326 fn to_arc(&self) -> ArcStatefulFunction<T, R>
327 where
328 Self: Clone + Send + Sync + 'static,
329 T: Send + Sync + 'static,
330 R: Send + 'static,
331 {
332 self.clone().into_arc()
333 }
334
335 /// Non-consuming conversion to a closure (`FnMut(&T) -> R`).
336 ///
337 /// Default implementation clones `self` into a `RefCell` and returns a
338 /// closure that calls `apply` on the interior mutable value.
339 fn to_fn(&self) -> impl FnMut(&T) -> R
340 where
341 Self: Sized + Clone + 'static,
342 {
343 self.clone().into_fn()
344 }
345
346 /// Convert to StatefulFunctionOnce without consuming self
347 ///
348 /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
349 /// Clones the current function and converts the clone to a one-time function.
350 ///
351 /// # Returns
352 ///
353 /// Returns a `BoxFunctionOnce<T, R>`
354 ///
355 /// # Examples
356 ///
357 /// ```rust
358 /// use qubit_function::{StatefulFunctionOnce, StatefulFunction,
359 /// BoxStatefulFunction};
360 ///
361 /// fn takes_once<F: StatefulFunctionOnce<i32, i32>>(func: F, value: &i32) {
362 /// let result = func.apply(value);
363 /// println!("Result: {}", result);
364 /// }
365 ///
366 /// let func = BoxStatefulFunction::new(|x: &i32| x * 2);
367 /// takes_once(func.to_once(), &5);
368 /// ```
369 fn to_once(&self) -> BoxFunctionOnce<T, R>
370 where
371 Self: Clone + 'static,
372 T: 'static,
373 R: 'static,
374 {
375 self.clone().into_once()
376 }
377}
378
379// ============================================================================
380// BoxStatefulFunction - Box<dyn FnMut(&T) -> R>
381// ============================================================================
382
383/// BoxStatefulFunction - stateful function wrapper based on `Box<dyn FnMut>`
384///
385/// A stateful function wrapper that provides single ownership with reusable stateful
386/// transformation. The stateful function consumes the input and can be called
387/// multiple times while maintaining internal state.
388///
389/// # Features
390///
391/// - **Based on**: `Box<dyn FnMut(&T) -> R>`
392/// - **Ownership**: Single ownership, cannot be cloned
393/// - **Reusability**: Can be called multiple times (each call consumes
394/// its input)
395/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
396/// - **Statefulness**: Can modify internal state between calls
397///
398/// # Author
399///
400/// Haixing Hu
401pub struct BoxStatefulFunction<T, R> {
402 function: Box<dyn FnMut(&T) -> R>,
403 name: Option<String>,
404}
405
406impl<T, R> BoxStatefulFunction<T, R> {
407 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
408 impl_function_common_methods!(
409 BoxStatefulFunction<T, R>,
410 (FnMut(&T) -> R + 'static),
411 |f| Box::new(f)
412 );
413
414 // Generates: when(), and_then(), compose()
415 impl_box_function_methods!(
416 BoxStatefulFunction<T, R>,
417 BoxConditionalStatefulFunction,
418 StatefulFunction
419 );
420}
421
422// Generates: constant() method for BoxStatefulFunction<T, R>
423impl_function_constant_method!(BoxStatefulFunction<T, R>, 'static);
424
425// Generates: identity() method for BoxStatefulFunction<T, T>
426impl_function_identity_method!(BoxStatefulFunction<T, T>);
427
428// Generates: Debug and Display implementations for BoxStatefulFunction<T, R>
429impl_function_debug_display!(BoxStatefulFunction<T, R>);
430
431// Implement StatefulFunction trait for BoxStatefulFunction<T, R>
432impl<T, R> StatefulFunction<T, R> for BoxStatefulFunction<T, R> {
433 fn apply(&mut self, t: &T) -> R {
434 (self.function)(t)
435 }
436
437 // Generates: into_box(), into_rc(), into_fn(), into_once()
438 impl_box_conversions!(
439 BoxStatefulFunction<T, R>,
440 RcStatefulFunction,
441 FnMut(&T) -> R,
442 BoxFunctionOnce
443 );
444}
445
446// ============================================================================
447// RcStatefulFunction - Rc<RefCell<dyn FnMut(&T) -> R>>
448// ============================================================================
449
450/// RcStatefulFunction - single-threaded function wrapper
451///
452/// A single-threaded, clonable function wrapper optimized for scenarios
453/// that require sharing without thread-safety overhead.
454///
455/// # Features
456///
457/// - **Based on**: `Rc<RefCell<dyn FnMut(&T) -> R>>`
458/// - **Ownership**: Shared ownership via reference counting (non-atomic)
459/// - **Reusability**: Can be called multiple times (each call consumes
460/// its input)
461/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
462/// - **Clonable**: Cheap cloning via `Rc::clone`
463/// - **Statefulness**: Can modify internal state between calls
464///
465/// # Author
466///
467/// Haixing Hu
468pub struct RcStatefulFunction<T, R> {
469 function: RcStatefulFn<T, R>,
470 name: Option<String>,
471}
472
473type RcStatefulFn<T, R> = Rc<RefCell<dyn FnMut(&T) -> R>>;
474
475impl<T, R> RcStatefulFunction<T, R> {
476 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
477 impl_function_common_methods!(
478 RcStatefulFunction<T, R>,
479 (FnMut(&T) -> R + 'static),
480 |f| Rc::new(RefCell::new(f))
481 );
482
483 // Generates: when(), and_then(), compose()
484 impl_shared_function_methods!(
485 RcStatefulFunction<T, R>,
486 RcConditionalStatefulFunction,
487 into_rc,
488 StatefulFunction,
489 'static
490 );
491}
492
493// Generates: constant() method for RcStatefulFunction<T, R>
494impl_function_constant_method!(RcStatefulFunction<T, R>, 'static);
495
496// Generates: identity() method for RcStatefulFunction<T, T>
497impl_function_identity_method!(RcStatefulFunction<T, T>);
498
499// Generates: Clone implementation for RcStatefulFunction<T, R>
500impl_function_clone!(RcStatefulFunction<T, R>);
501
502// Generates: Debug and Display implementations for RcStatefulFunction<T, R>
503impl_function_debug_display!(RcStatefulFunction<T, R>);
504
505// Implement StatefulFunction trait for RcStatefulFunction<T, R>
506impl<T, R> StatefulFunction<T, R> for RcStatefulFunction<T, R> {
507 fn apply(&mut self, t: &T) -> R {
508 (self.function.borrow_mut())(t)
509 }
510
511 // Use macro to implement conversion methods
512 impl_rc_conversions!(
513 RcStatefulFunction<T, R>,
514 BoxStatefulFunction,
515 BoxFunctionOnce,
516 FnMut(t: &T) -> R
517 );
518}
519
520// ============================================================================
521// ArcStatefulFunction - Arc<Mutex<dyn FnMut(&T) -> R + Send>>
522// ============================================================================
523
524/// ArcStatefulFunction - thread-safe function wrapper
525///
526/// A thread-safe, clonable function wrapper suitable for multi-threaded
527/// scenarios. Can be called multiple times and shared across threads
528/// while maintaining internal state.
529///
530/// # Features
531///
532/// - **Based on**: `Arc<Mutex<dyn FnMut(&T) -> R + Send>>`
533/// - **Ownership**: Shared ownership via reference counting
534/// - **Reusability**: Can be called multiple times (each call consumes
535/// its input)
536/// - **Thread Safety**: Thread-safe (`Send` required)
537/// - **Clonable**: Cheap cloning via `Arc::clone`
538/// - **Statefulness**: Can modify internal state between calls
539///
540/// # Author
541///
542/// Haixing Hu
543pub struct ArcStatefulFunction<T, R> {
544 function: ArcStatefulFn<T, R>,
545 name: Option<String>,
546}
547
548type ArcStatefulFn<T, R> = Arc<Mutex<dyn FnMut(&T) -> R + Send + 'static>>;
549
550impl<T, R> ArcStatefulFunction<T, R> {
551 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
552 impl_function_common_methods!(
553 ArcStatefulFunction<T, R>,
554 (FnMut(&T) -> R + Send + 'static),
555 |f| Arc::new(Mutex::new(f))
556 );
557
558 // Generates: when(), and_then(), compose()
559 impl_shared_function_methods!(
560 ArcStatefulFunction<T, R>,
561 ArcConditionalStatefulFunction,
562 into_arc,
563 StatefulFunction,
564 Send + Sync + 'static
565 );
566}
567
568// Generates: constant() method for ArcStatefulFunction<T, R>
569impl_function_constant_method!(ArcStatefulFunction<T, R>, Send + Sync + 'static);
570
571// Generates: identity() method for ArcStatefulFunction<T, T>
572impl_function_identity_method!(ArcStatefulFunction<T, T>);
573
574// Generates: Clone implementation for ArcStatefulFunction<T, R>
575impl_function_clone!(ArcStatefulFunction<T, R>);
576
577// Generates: Debug and Display implementations for ArcStatefulFunction<T, R>
578impl_function_debug_display!(ArcStatefulFunction<T, R>);
579
580// Implement StatefulFunction trait for ArcStatefulFunction<T, R>
581impl<T, R> StatefulFunction<T, R> for ArcStatefulFunction<T, R> {
582 fn apply(&mut self, t: &T) -> R {
583 (self.function.lock())(t)
584 }
585
586 // Use macro to implement conversion methods
587 impl_arc_conversions!(
588 ArcStatefulFunction<T, R>,
589 BoxStatefulFunction,
590 RcStatefulFunction,
591 BoxFunctionOnce,
592 FnMut(t: &T) -> R
593 );
594}
595
596// ============================================================================
597// Blanket implementation for standard FnMut trait
598// ============================================================================
599
600/// Implement StatefulFunction<T, R> for any type that implements FnMut(&T) -> R
601///
602/// This allows closures to be used directly with our StatefulFunction trait
603/// without wrapping.
604///
605/// # Examples
606///
607/// ```rust
608/// use qubit_function::StatefulFunction;
609///
610/// let mut counter = 0;
611/// let mut function = |x: i32| {
612/// counter += 1;
613/// x + counter
614/// };
615///
616/// assert_eq!(function.apply(10), 11);
617/// assert_eq!(function.apply(10), 12);
618/// ```
619///
620/// # Author
621///
622/// Haixing Hu
623impl<F, T, R> StatefulFunction<T, R> for F
624where
625 F: FnMut(&T) -> R,
626{
627 fn apply(&mut self, t: &T) -> R {
628 self(t)
629 }
630
631 fn into_box(self) -> BoxStatefulFunction<T, R>
632 where
633 Self: Sized + 'static,
634 T: 'static,
635 R: 'static,
636 {
637 BoxStatefulFunction::new(self)
638 }
639
640 fn into_rc(self) -> RcStatefulFunction<T, R>
641 where
642 Self: Sized + 'static,
643 T: 'static,
644 R: 'static,
645 {
646 RcStatefulFunction::new(self)
647 }
648
649 fn into_arc(self) -> ArcStatefulFunction<T, R>
650 where
651 Self: Sized + Send + 'static,
652 T: Send + Sync + 'static,
653 R: 'static,
654 {
655 ArcStatefulFunction::new(self)
656 }
657
658 fn into_fn(self) -> impl FnMut(&T) -> R
659 where
660 Self: Sized + 'static,
661 {
662 self
663 }
664
665 fn to_box(&self) -> BoxStatefulFunction<T, R>
666 where
667 Self: Sized + Clone + 'static,
668 T: 'static,
669 R: 'static,
670 {
671 self.clone().into_box()
672 }
673
674 fn to_rc(&self) -> RcStatefulFunction<T, R>
675 where
676 Self: Sized + Clone + 'static,
677 T: 'static,
678 R: 'static,
679 {
680 self.clone().into_rc()
681 }
682
683 fn to_arc(&self) -> ArcStatefulFunction<T, R>
684 where
685 Self: Sized + Clone + Send + Sync + 'static,
686 T: Send + Sync + 'static,
687 R: 'static,
688 {
689 self.clone().into_arc()
690 }
691
692 fn to_fn(&self) -> impl FnMut(&T) -> R
693 where
694 Self: Sized + Clone + 'static,
695 {
696 self.clone()
697 }
698
699 fn into_once(self) -> BoxFunctionOnce<T, R>
700 where
701 Self: Sized + 'static,
702 T: 'static,
703 R: 'static,
704 {
705 BoxFunctionOnce::new(self)
706 }
707
708 fn to_once(&self) -> BoxFunctionOnce<T, R>
709 where
710 Self: Sized + Clone + 'static,
711 T: 'static,
712 R: 'static,
713 {
714 BoxFunctionOnce::new(self.clone())
715 }
716}
717
718// ============================================================================
719// FnStatefulFunctionOps - Extension trait for closure functions
720// ============================================================================
721
722// Generates: FnStatefulFunctionOps trait and blanket implementation
723impl_fn_ops_trait!(
724 (FnMut(&T) -> R),
725 FnStatefulFunctionOps,
726 BoxStatefulFunction,
727 StatefulFunction,
728 BoxConditionalStatefulFunction
729);
730
731// ============================================================================
732// BoxConditionalStatefulFunction - Box-based Conditional StatefulFunction
733// ============================================================================
734
735/// BoxConditionalStatefulFunction struct
736///
737/// A conditional function that only executes when a predicate is satisfied.
738/// Uses `BoxStatefulFunction` and `BoxPredicate` for single ownership semantics.
739///
740/// This type is typically created by calling `BoxStatefulFunction::when()` and is
741/// designed to work with the `or_else()` method to create if-then-else
742/// logic.
743///
744/// # Features
745///
746/// - **Single Ownership**: Not cloneable, consumes `self` on use
747/// - **Conditional Execution**: Only maps when predicate returns `true`
748/// - **Chainable**: Can add `or_else` branch to create if-then-else
749/// logic
750/// - **Implements StatefulFunction**: Can be used anywhere a `StatefulFunction` is expected
751///
752/// # Examples
753///
754/// ```rust
755/// use qubit_function::{StatefulFunction, BoxStatefulFunction};
756///
757/// let mut high_count = 0;
758/// let mut low_count = 0;
759///
760/// let mut function = BoxStatefulFunction::new(move |x: i32| {
761/// high_count += 1;
762/// x * 2
763/// })
764/// .when(|x: &i32| *x >= 10)
765/// .or_else(move |x| {
766/// low_count += 1;
767/// x + 1
768/// });
769///
770/// assert_eq!(function.apply(15), 30); // when branch executed
771/// assert_eq!(function.apply(5), 6); // or_else branch executed
772/// ```
773///
774/// # Author
775///
776/// Haixing Hu
777pub struct BoxConditionalStatefulFunction<T, R> {
778 function: BoxStatefulFunction<T, R>,
779 predicate: BoxPredicate<T>,
780}
781
782// Use macro to generate conditional function implementations
783impl_box_conditional_function!(
784 BoxConditionalStatefulFunction<T, R>,
785 BoxStatefulFunction,
786 StatefulFunction
787);
788
789// Use macro to generate conditional function debug and display implementations
790impl_conditional_function_debug_display!(BoxConditionalStatefulFunction<T, R>);
791
792// ============================================================================
793// RcConditionalStatefulFunction - Rc-based Conditional StatefulFunction
794// ============================================================================
795
796/// RcConditionalStatefulFunction struct
797///
798/// A single-threaded conditional function that only executes when a
799/// predicate is satisfied. Uses `RcStatefulFunction` and `RcPredicate` for shared
800/// ownership within a single thread.
801///
802/// This type is typically created by calling `RcStatefulFunction::when()` and is
803/// designed to work with the `or_else()` method to create if-then-else
804/// logic.
805///
806/// # Features
807///
808/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
809/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
810/// - **Conditional Execution**: Only maps when predicate returns `true`
811/// - **No Lock Overhead**: More efficient than `ArcConditionalStatefulFunction`
812///
813/// # Examples
814///
815/// ```rust
816/// use qubit_function::{StatefulFunction, RcStatefulFunction};
817///
818/// let mut function = RcStatefulFunction::new(|x: i32| x * 2)
819/// .when(|x: &i32| *x > 0)
820/// .or_else(|x: i32| -x);
821///
822/// let mut function_clone = function.clone();
823///
824/// assert_eq!(function.apply(5), 10);
825/// assert_eq!(function_clone.apply(-5), 5);
826/// ```
827///
828/// # Author
829///
830/// Haixing Hu
831pub struct RcConditionalStatefulFunction<T, R> {
832 function: RcStatefulFunction<T, R>,
833 predicate: RcPredicate<T>,
834}
835
836// Use macro to generate conditional function implementations
837impl_shared_conditional_function!(
838 RcConditionalStatefulFunction<T, R>,
839 RcStatefulFunction,
840 StatefulFunction,
841 'static
842);
843
844// Use macro to generate conditional function clone implementations
845impl_conditional_function_clone!(RcConditionalStatefulFunction<T, R>);
846
847// Use macro to generate conditional function debug and display implementations
848impl_conditional_function_debug_display!(RcConditionalStatefulFunction<T, R>);
849
850// ============================================================================
851// ArcConditionalStatefulFunction - Arc-based Conditional StatefulFunction
852// ============================================================================
853
854/// ArcConditionalStatefulFunction struct
855///
856/// A thread-safe conditional function that only executes when a predicate
857/// is satisfied. Uses `ArcStatefulFunction` and `ArcPredicate` for shared
858/// ownership across threads.
859///
860/// This type is typically created by calling `ArcStatefulFunction::when()` and is
861/// designed to work with the `or_else()` method to create if-then-else
862/// logic.
863///
864/// # Features
865///
866/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
867/// - **Thread-Safe**: Implements `Send`, safe for concurrent use
868/// - **Conditional Execution**: Only maps when predicate returns `true`
869/// - **Chainable**: Can add `or_else` branch to create if-then-else
870/// logic
871///
872/// # Examples
873///
874/// ```rust
875/// use qubit_function::{StatefulFunction, ArcStatefulFunction};
876///
877/// let mut function = ArcStatefulFunction::new(|x: i32| x * 2)
878/// .when(|x: &i32| *x > 0)
879/// .or_else(|x: i32| -x);
880///
881/// let mut function_clone = function.clone();
882///
883/// assert_eq!(function.apply(5), 10);
884/// assert_eq!(function_clone.apply(-5), 5);
885/// ```
886///
887/// # Author
888///
889/// Haixing Hu
890pub struct ArcConditionalStatefulFunction<T, R> {
891 function: ArcStatefulFunction<T, R>,
892 predicate: ArcPredicate<T>,
893}
894
895// Use macro to generate conditional function implementations
896impl_shared_conditional_function!(
897 ArcConditionalStatefulFunction<T, R>,
898 ArcStatefulFunction,
899 StatefulFunction,
900 Send + Sync + 'static
901);
902
903// Use macro to generate conditional function clone implementations
904impl_conditional_function_clone!(ArcConditionalStatefulFunction<T, R>);
905
906// Use macro to generate conditional function debug and display implementations
907impl_conditional_function_debug_display!(ArcConditionalStatefulFunction<T, R>);