Skip to main content

qubit_function/functions/bi_function_once/
box_bi_function_once.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 `BoxBiFunctionOnce` public type.
12
13use super::{
14    BiFunctionOnce,
15    BiPredicate,
16    BoxConditionalBiFunctionOnce,
17    FunctionOnce,
18    impl_box_function_methods,
19    impl_box_once_conversions,
20    impl_closure_once_trait,
21    impl_function_common_methods,
22    impl_function_constant_method,
23    impl_function_debug_display,
24};
25
26type BoxBiFunctionOnceFn<T, U, R> = Box<dyn FnOnce(&T, &U) -> R>;
27
28// ============================================================================
29// BoxBiFunctionOnce - Box<dyn FnOnce(&T, &U) -> R>
30// ============================================================================
31
32/// BoxBiFunctionOnce - consuming bi-function wrapper based on
33/// `Box<dyn FnOnce>`
34///
35/// A bi-function wrapper that provides single ownership with one-time use
36/// semantics. Consumes self and borrows both input values.
37///
38/// # Features
39///
40/// - **Based on**: `Box<dyn FnOnce(&T, &U) -> R>`
41/// - **Ownership**: Single ownership, cannot be cloned
42/// - **Reusability**: Can only be called once (consumes self)
43/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
44///
45pub struct BoxBiFunctionOnce<T, U, R> {
46    pub(super) function: BoxBiFunctionOnceFn<T, U, R>,
47    pub(super) name: Option<String>,
48}
49
50// Implement BoxBiFunctionOnce
51impl<T, U, R> BoxBiFunctionOnce<T, U, R> {
52    // Generate new(), new_with_name(), new_with_optional_name(), name(), set_name()
53    impl_function_common_methods!(
54        BoxBiFunctionOnce<T, U, R>,
55        (FnOnce(&T, &U) -> R + 'static),
56        |f| Box::new(f)
57    );
58
59    // Generate when(), and_then()
60    impl_box_function_methods!(
61        BoxBiFunctionOnce<T, U, R>,
62        BoxConditionalBiFunctionOnce,
63        FunctionOnce
64    );
65}
66
67// Implement BiFunctionOnce trait for BoxBiFunctionOnce
68impl<T, U, R> BiFunctionOnce<T, U, R> for BoxBiFunctionOnce<T, U, R> {
69    fn apply(self, first: &T, second: &U) -> R {
70        (self.function)(first, second)
71    }
72
73    // Generate into_box(), into_fn(), to_box()
74    impl_box_once_conversions!(
75        BoxBiFunctionOnce<T, U, R>,
76        BiFunctionOnce,
77        FnOnce(&T, &U) -> R
78    );
79}
80
81// Implement constant method for BoxBiFunctionOnce
82impl_function_constant_method!(BoxBiFunctionOnce<T, U, R>);
83
84// Use macro to generate Debug and Display implementations
85impl_function_debug_display!(BoxBiFunctionOnce<T, U, R>);
86
87// ============================================================================
88// Blanket implementation for standard FnOnce trait
89// ============================================================================
90
91// Implement BiFunctionOnce for all FnOnce(&T, &U) -> R using macro
92impl_closure_once_trait!(
93    BiFunctionOnce<T, U, R>,
94    apply,
95    BoxBiFunctionOnce,
96    FnOnce(first: &T, second: &U) -> R
97);