Skip to main content

card_est_array/impls/
default_estimator.rs

1/*
2 * SPDX-FileCopyrightText: 2024 Matteo Dell'Acqua
3 * SPDX-FileCopyrightText: 2025 Sebastiano Vigna
4 *
5 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
6 */
7
8use crate::traits::*;
9use std::borrow::Borrow;
10
11/// A default estimator for generic [`EstimationLogic`] and backends.
12pub struct DefaultEstimator<L: EstimationLogic, BL: Borrow<L>, B> {
13    logic: BL,
14    backend: B,
15    _marker: std::marker::PhantomData<L>,
16}
17
18impl<L: EstimationLogic, BL: Borrow<L>, B> DefaultEstimator<L, BL, B> {
19    /// Creates a new default estimator for the specified logic and backend.
20    ///
21    /// # Arguments
22    /// * `logic`: the estimator logic.
23    /// * `backend`: the estimator's backend.
24    pub const fn new(logic: BL, backend: B) -> Self {
25        Self {
26            logic,
27            backend,
28            _marker: std::marker::PhantomData,
29        }
30    }
31}
32
33impl<L: EstimationLogic + Clone, BL: Borrow<L>, B: AsRef<L::Backend>> AsRef<L::Backend>
34    for DefaultEstimator<L, BL, B>
35{
36    #[inline(always)]
37    fn as_ref(&self) -> &L::Backend {
38        self.backend.as_ref()
39    }
40}
41
42impl<L: EstimationLogic + Clone, BL: Borrow<L>, B: AsMut<L::Backend>> AsMut<L::Backend>
43    for DefaultEstimator<L, BL, B>
44{
45    #[inline(always)]
46    fn as_mut(&mut self) -> &mut L::Backend {
47        self.backend.as_mut()
48    }
49}
50
51impl<L: EstimationLogic + Clone, BL: Borrow<L>, B: AsRef<L::Backend>> Estimator<L>
52    for DefaultEstimator<L, BL, B>
53where
54    for<'a> Box<L::Backend>: From<&'a L::Backend>,
55{
56    type OwnedEstimator = DefaultEstimator<L, L, Box<L::Backend>>;
57
58    #[inline(always)]
59    fn logic(&self) -> &L {
60        self.logic.borrow()
61    }
62
63    #[inline(always)]
64    fn estimate(&self) -> f64 {
65        self.logic.borrow().estimate(self.backend.as_ref())
66    }
67
68    #[inline(always)]
69    fn into_owned(self) -> Self::OwnedEstimator {
70        DefaultEstimator::new(
71            self.logic.borrow().clone(),
72            Box::from(self.backend.as_ref()),
73        )
74    }
75}
76
77impl<L: EstimationLogic + Clone, BL: Borrow<L>, B: AsRef<L::Backend> + AsMut<L::Backend>>
78    EstimatorMut<L> for DefaultEstimator<L, BL, B>
79where
80    for<'a> Box<L::Backend>: From<&'a L::Backend>,
81{
82    #[inline(always)]
83    fn add(&mut self, element: impl Borrow<L::Item>) {
84        self.logic.borrow().add(self.backend.as_mut(), element)
85    }
86
87    #[inline(always)]
88    fn clear(&mut self) {
89        self.logic.borrow().clear(self.backend.as_mut())
90    }
91
92    #[inline(always)]
93    fn set(&mut self, backend: &L::Backend) {
94        self.logic.borrow().set(self.backend.as_mut(), backend);
95    }
96}
97
98impl<
99    L: EstimationLogic + MergeEstimationLogic + Clone,
100    BL: Borrow<L>,
101    B: AsRef<L::Backend> + AsMut<L::Backend>,
102> MergeEstimator<L> for DefaultEstimator<L, BL, B>
103where
104    for<'a> Box<L::Backend>: From<&'a L::Backend>,
105{
106    #[inline(always)]
107    fn merge(&mut self, other: &L::Backend) {
108        self.logic.borrow().merge(self.backend.as_mut(), other)
109    }
110
111    #[inline(always)]
112    fn merge_with_helper(
113        &mut self,
114        other: &L::Backend,
115        helper: &mut <L as MergeEstimationLogic>::Helper,
116    ) {
117        self.logic
118            .borrow()
119            .merge_with_helper(self.backend.as_mut(), other, helper)
120    }
121}