prism3_function/functions/
function.rs

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