Skip to main content

antecedent_data/
aligned_buffer.rs

1//! Growable aligned f64 scratch buffers.
2//!
3//! SPDX-License-Identifier: MIT OR Apache-2.0
4
5/// Aligned growable `f64` buffer for design-matrix materialization.
6#[derive(Clone, Debug, Default)]
7pub struct AlignedBuffer<T> {
8    data: Vec<T>,
9}
10
11impl<T: Copy + Default> AlignedBuffer<T> {
12    /// Empty buffer.
13    #[must_use]
14    pub const fn new() -> Self {
15        Self { data: Vec::new() }
16    }
17
18    /// Ensure at least `len` elements (grows, never shrinks; fills with default).
19    pub fn resize(&mut self, len: usize) {
20        if self.data.len() < len {
21            self.data.resize(len, T::default());
22        }
23    }
24
25    /// Borrow as slice of logical length `len` (must have been resized).
26    ///
27    /// # Panics
28    ///
29    /// When `len > self.data.len()`.
30    #[must_use]
31    pub fn as_slice(&self, len: usize) -> &[T] {
32        &self.data[..len]
33    }
34
35    /// Mutable borrow of logical length `len`.
36    ///
37    /// # Panics
38    ///
39    /// When `len > self.data.len()`.
40    pub fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
41        &mut self.data[..len]
42    }
43
44    /// Underlying capacity in elements.
45    #[must_use]
46    pub fn capacity(&self) -> usize {
47        self.data.capacity()
48    }
49
50    /// Current allocated length (may exceed logical use).
51    #[must_use]
52    pub fn len(&self) -> usize {
53        self.data.len()
54    }
55
56    /// Whether empty.
57    #[must_use]
58    pub fn is_empty(&self) -> bool {
59        self.data.is_empty()
60    }
61}
62
63impl AlignedBuffer<f64> {
64    /// Ensure capacity then return mutable slice of length `len`.
65    pub fn prepare_mut(&mut self, len: usize) -> &mut [f64] {
66        self.resize(len);
67        self.as_mut_slice(len)
68    }
69}