Skip to content

Commit 4b78bc1

Browse files
authored
Merge pull request #500 from Nitrokey/vec-drain-generic
Implement `Vec::drain`, `as_(mut_)view` on the `*Inner` types, generic over `Storage`
2 parents 1a33fec + b01fcfb commit 4b78bc1

14 files changed

+712
-275
lines changed

src/binary_heap.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,16 @@ impl<T, K, const N: usize> BinaryHeap<T, K, N> {
184184
pub fn into_vec(self) -> Vec<T, N> {
185185
self.data
186186
}
187+
}
187188

189+
impl<T, K, S: VecStorage<T>> BinaryHeapInner<T, K, S> {
188190
/// Get a reference to the `BinaryHeap`, erasing the `N` const-generic.
189191
pub fn as_view(&self) -> &BinaryHeapView<T, K> {
190-
self
192+
S::as_binary_heap_view(self)
191193
}
192194
/// Get a mutable reference to the `BinaryHeap`, erasing the `N` const-generic.
193195
pub fn as_mut_view(&mut self) -> &mut BinaryHeapView<T, K> {
194-
self
196+
S::as_binary_heap_mut_view(self)
195197
}
196198
}
197199

src/defmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Defmt implementations for heapless types
22
33
use crate::{
4-
string::StringInner,
4+
string::{StringInner, StringStorage},
55
vec::{VecInner, VecStorage},
66
};
77
use defmt::Formatter;
@@ -15,7 +15,7 @@ where
1515
}
1616
}
1717

18-
impl<S: VecStorage<u8> + ?Sized> defmt::Format for StringInner<S>
18+
impl<S: StringStorage + ?Sized> defmt::Format for StringInner<S>
1919
where
2020
u8: defmt::Format,
2121
{

src/deque.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,19 +186,19 @@ impl<T, const N: usize> Deque<T, N> {
186186
self.back - self.front
187187
}
188188
}
189+
}
189190

191+
impl<T, S: VecStorage<T> + ?Sized> DequeInner<T, S> {
190192
/// Get a reference to the `Deque`, erasing the `N` const-generic.
191193
pub fn as_view(&self) -> &DequeView<T> {
192-
self
194+
S::as_deque_view(self)
193195
}
194196

195197
/// Get a mutable reference to the `Deque`, erasing the `N` const-generic.
196198
pub fn as_mut_view(&mut self) -> &mut DequeView<T> {
197-
self
199+
S::as_deque_mut_view(self)
198200
}
199-
}
200201

201-
impl<T, S: VecStorage<T> + ?Sized> DequeInner<T, S> {
202202
/// Returns the maximum number of elements the deque can hold.
203203
pub fn storage_capacity(&self) -> usize {
204204
self.buffer.borrow().len()

src/histbuf.rs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ use core::slice;
4141
mod storage {
4242
use core::mem::MaybeUninit;
4343

44+
use super::{HistoryBufferInner, HistoryBufferView};
45+
4446
/// Trait defining how data for a container is stored.
4547
///
4648
/// There's two implementations available:
@@ -72,6 +74,14 @@ mod storage {
7274
// part of the sealed trait so that no trait is publicly implemented by `OwnedHistBufStorage` besides `Storage`
7375
fn borrow(&self) -> &[MaybeUninit<T>];
7476
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>];
77+
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T>
78+
where
79+
Self: HistBufStorage<T>;
80+
fn as_hist_buf_mut_view(
81+
this: &mut HistoryBufferInner<T, Self>,
82+
) -> &mut HistoryBufferView<T>
83+
where
84+
Self: HistBufStorage<T>;
7585
}
7686

7787
// One sealed layer of indirection to hide the internal details (The MaybeUninit).
@@ -91,6 +101,18 @@ mod storage {
91101
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
92102
&mut self.buffer
93103
}
104+
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T>
105+
where
106+
Self: HistBufStorage<T>,
107+
{
108+
this
109+
}
110+
fn as_hist_buf_mut_view(this: &mut HistoryBufferInner<T, Self>) -> &mut HistoryBufferView<T>
111+
where
112+
Self: HistBufStorage<T>,
113+
{
114+
this
115+
}
94116
}
95117
impl<T, const N: usize> HistBufStorage<T> for OwnedHistBufStorage<T, N> {}
96118

@@ -101,6 +123,18 @@ mod storage {
101123
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
102124
&mut self.buffer
103125
}
126+
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T>
127+
where
128+
Self: HistBufStorage<T>,
129+
{
130+
this
131+
}
132+
fn as_hist_buf_mut_view(this: &mut HistoryBufferInner<T, Self>) -> &mut HistoryBufferView<T>
133+
where
134+
Self: HistBufStorage<T>,
135+
{
136+
this
137+
}
104138
}
105139
impl<T> HistBufStorage<T> for ViewHistBufStorage<T> {}
106140
}
@@ -221,18 +255,6 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
221255
filled: false,
222256
}
223257
}
224-
225-
/// Get a reference to the `HistoryBuffer`, erasing the `N` const-generic.
226-
#[inline]
227-
pub const fn as_view(&self) -> &HistoryBufferView<T> {
228-
self
229-
}
230-
231-
/// Get a mutable reference to the `HistoryBuffer`, erasing the `N` const-generic.
232-
#[inline]
233-
pub fn as_mut_view(&mut self) -> &mut HistoryBufferView<T> {
234-
self
235-
}
236258
}
237259

238260
impl<T, const N: usize> HistoryBuffer<T, N>
@@ -264,6 +286,17 @@ where
264286
}
265287
}
266288
impl<T: Copy, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
289+
/// Get a reference to the `HistoryBuffer`, erasing the `N` const-generic.
290+
#[inline]
291+
pub fn as_view(&self) -> &HistoryBufferView<T> {
292+
S::as_hist_buf_view(self)
293+
}
294+
295+
/// Get a mutable reference to the `HistoryBuffer`, erasing the `N` const-generic.
296+
#[inline]
297+
pub fn as_mut_view(&mut self) -> &mut HistoryBufferView<T> {
298+
S::as_hist_buf_mut_view(self)
299+
}
267300
/// Clears the buffer, replacing every element with the given value.
268301
pub fn clear_with(&mut self, t: T) {
269302
// SAFETY: we reset the values just after

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ pub mod storage;
181181
pub mod string;
182182
pub mod vec;
183183

184+
// Workaround a compiler ICE in rust 1.83 to 1.86
185+
// https://github.com/rust-lang/rust/issues/138979#issuecomment-2760839948
186+
#[expect(dead_code)]
187+
fn dead_code_ice_workaround() {}
188+
184189
#[cfg(feature = "serde")]
185190
mod de;
186191
#[cfg(feature = "serde")]

src/linear_map.rs

Lines changed: 98 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,103 @@
44
55
use core::{borrow::Borrow, fmt, mem, ops, slice};
66

7-
use crate::vec::{OwnedVecStorage, Vec, VecInner, VecStorage, ViewVecStorage};
7+
use crate::vec::{OwnedVecStorage, Vec, VecInner, ViewVecStorage};
8+
9+
mod storage {
10+
use crate::vec::{OwnedVecStorage, VecStorage, ViewVecStorage};
11+
12+
use super::{LinearMapInner, LinearMapView};
13+
14+
/// Trait defining how data for a [`LinearMap`](super::LinearMap) is stored.
15+
///
16+
/// There's two implementations available:
17+
///
18+
/// - [`OwnedStorage`]: stores the data in an array whose size is known at compile time.
19+
/// - [`ViewStorage`]: stores the data in an unsized slice
20+
///
21+
/// This allows [`LinearMap`] to be generic over either sized or unsized storage. The [`linear_map`](super)
22+
/// module contains a [`LinearMapInner`] struct that's generic on [`LinearMapStorage`],
23+
/// and two type aliases for convenience:
24+
///
25+
/// - [`LinearMap<N>`](crate::linear_map::LinearMap) = `LinearMapInner<OwnedStorage<u8, N>>`
26+
/// - [`LinearMapView<T>`](crate::linear_map::LinearMapView) = `LinearMapInner<ViewStorage<u8>>`
27+
///
28+
/// `LinearMap` can be unsized into `StrinsgView`, either by unsizing coercions such as `&mut LinearMap -> &mut LinearMapView` or
29+
/// `Box<LinearMap> -> Box<LinearMapView>`, or explicitly with [`.as_view()`](crate::linear_map::LinearMap::as_view) or [`.as_mut_view()`](crate::linear_map::LinearMap::as_mut_view).
30+
///
31+
/// This trait is sealed, so you cannot implement it for your own types. You can only use
32+
/// the implementations provided by this crate.
33+
///
34+
/// [`LinearMapInner`]: super::LinearMapInner
35+
/// [`LinearMap`]: super::LinearMap
36+
/// [`OwnedStorage`]: super::OwnedStorage
37+
/// [`ViewStorage`]: super::ViewStorage
38+
pub trait LinearMapStorage<K, V>: LinearMapStorageSealed<K, V> {}
39+
pub trait LinearMapStorageSealed<K, V>: VecStorage<(K, V)> {
40+
fn as_linear_map_view(this: &LinearMapInner<K, V, Self>) -> &LinearMapView<K, V>
41+
where
42+
Self: LinearMapStorage<K, V>;
43+
fn as_linear_map_mut_view(
44+
this: &mut LinearMapInner<K, V, Self>,
45+
) -> &mut LinearMapView<K, V>
46+
where
47+
Self: LinearMapStorage<K, V>;
48+
}
49+
50+
impl<K, V, const N: usize> LinearMapStorage<K, V> for OwnedVecStorage<(K, V), N> {}
51+
impl<K, V, const N: usize> LinearMapStorageSealed<K, V> for OwnedVecStorage<(K, V), N> {
52+
fn as_linear_map_view(this: &LinearMapInner<K, V, Self>) -> &LinearMapView<K, V>
53+
where
54+
Self: LinearMapStorage<K, V>,
55+
{
56+
this
57+
}
58+
fn as_linear_map_mut_view(this: &mut LinearMapInner<K, V, Self>) -> &mut LinearMapView<K, V>
59+
where
60+
Self: LinearMapStorage<K, V>,
61+
{
62+
this
63+
}
64+
}
65+
66+
impl<K, V> LinearMapStorage<K, V> for ViewVecStorage<(K, V)> {}
67+
68+
impl<K, V> LinearMapStorageSealed<K, V> for ViewVecStorage<(K, V)> {
69+
fn as_linear_map_view(this: &LinearMapInner<K, V, Self>) -> &LinearMapView<K, V>
70+
where
71+
Self: LinearMapStorage<K, V>,
72+
{
73+
this
74+
}
75+
fn as_linear_map_mut_view(this: &mut LinearMapInner<K, V, Self>) -> &mut LinearMapView<K, V>
76+
where
77+
Self: LinearMapStorage<K, V>,
78+
{
79+
this
80+
}
81+
}
82+
}
83+
84+
pub use storage::LinearMapStorage;
85+
/// Implementation of [`LinearMapStorage`] that stores the data in an array whose size is known at compile time.
86+
pub type OwnedStorage<K, V, const N: usize> = OwnedVecStorage<(K, V), N>;
87+
/// Implementation of [`LinearMapStorage`] that stores the data in an unsized slice.
88+
pub type ViewStorage<K, V> = ViewVecStorage<(K, V)>;
889

990
/// Base struct for [`LinearMap`] and [`LinearMapView`]
10-
pub struct LinearMapInner<K, V, S: VecStorage<(K, V)> + ?Sized> {
91+
pub struct LinearMapInner<K, V, S: LinearMapStorage<K, V> + ?Sized> {
1192
pub(crate) buffer: VecInner<(K, V), S>,
1293
}
1394

1495
/// A fixed capacity map/dictionary that performs lookups via linear search.
1596
///
1697
/// Note that as this map doesn't use hashing so most operations are *O*(n) instead of *O*(1).
17-
pub type LinearMap<K, V, const N: usize> = LinearMapInner<K, V, OwnedVecStorage<(K, V), N>>;
98+
pub type LinearMap<K, V, const N: usize> = LinearMapInner<K, V, OwnedStorage<K, V, N>>;
1899

19100
/// A dynamic capacity map/dictionary that performs lookups via linear search.
20101
///
21102
/// Note that as this map doesn't use hashing so most operations are *O*(n) instead of *O*(1).
22-
pub type LinearMapView<K, V> = LinearMapInner<K, V, ViewVecStorage<(K, V)>>;
103+
pub type LinearMapView<K, V> = LinearMapInner<K, V, ViewStorage<K, V>>;
23104

24105
impl<K, V, const N: usize> LinearMap<K, V, N> {
25106
/// Creates an empty `LinearMap`.
@@ -38,22 +119,22 @@ impl<K, V, const N: usize> LinearMap<K, V, N> {
38119
pub const fn new() -> Self {
39120
Self { buffer: Vec::new() }
40121
}
122+
}
41123

124+
impl<K, V, S: LinearMapStorage<K, V> + ?Sized> LinearMapInner<K, V, S>
125+
where
126+
K: Eq,
127+
{
42128
/// Get a reference to the `LinearMap`, erasing the `N` const-generic.
43129
pub fn as_view(&self) -> &LinearMapView<K, V> {
44-
self
130+
S::as_linear_map_view(self)
45131
}
46132

47133
/// Get a mutable reference to the `LinearMap`, erasing the `N` const-generic.
48134
pub fn as_mut_view(&mut self) -> &mut LinearMapView<K, V> {
49-
self
135+
S::as_linear_map_mut_view(self)
50136
}
51-
}
52137

53-
impl<K, V, S: VecStorage<(K, V)> + ?Sized> LinearMapInner<K, V, S>
54-
where
55-
K: Eq,
56-
{
57138
/// Returns the number of elements that the map can hold.
58139
///
59140
/// Computes in *O*(1) time.
@@ -388,7 +469,7 @@ where
388469
}
389470
}
390471

391-
impl<K, V, Q, S: VecStorage<(K, V)> + ?Sized> ops::Index<&'_ Q> for LinearMapInner<K, V, S>
472+
impl<K, V, Q, S: LinearMapStorage<K, V> + ?Sized> ops::Index<&'_ Q> for LinearMapInner<K, V, S>
392473
where
393474
K: Borrow<Q> + Eq,
394475
Q: Eq + ?Sized,
@@ -400,7 +481,7 @@ where
400481
}
401482
}
402483

403-
impl<K, V, Q, S: VecStorage<(K, V)> + ?Sized> ops::IndexMut<&'_ Q> for LinearMapInner<K, V, S>
484+
impl<K, V, Q, S: LinearMapStorage<K, V> + ?Sized> ops::IndexMut<&'_ Q> for LinearMapInner<K, V, S>
404485
where
405486
K: Borrow<Q> + Eq,
406487
Q: Eq + ?Sized,
@@ -431,7 +512,7 @@ where
431512
}
432513
}
433514

434-
impl<K, V, S: VecStorage<(K, V)> + ?Sized> fmt::Debug for LinearMapInner<K, V, S>
515+
impl<K, V, S: LinearMapStorage<K, V> + ?Sized> fmt::Debug for LinearMapInner<K, V, S>
435516
where
436517
K: Eq + fmt::Debug,
437518
V: fmt::Debug,
@@ -489,7 +570,7 @@ where
489570
}
490571
}
491572

492-
impl<'a, K, V, S: VecStorage<(K, V)> + ?Sized> IntoIterator for &'a LinearMapInner<K, V, S>
573+
impl<'a, K, V, S: LinearMapStorage<K, V> + ?Sized> IntoIterator for &'a LinearMapInner<K, V, S>
493574
where
494575
K: Eq,
495576
{
@@ -533,7 +614,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
533614
}
534615
}
535616

536-
impl<K, V, S1: VecStorage<(K, V)> + ?Sized, S2: VecStorage<(K, V)> + ?Sized>
617+
impl<K, V, S1: LinearMapStorage<K, V> + ?Sized, S2: LinearMapStorage<K, V> + ?Sized>
537618
PartialEq<LinearMapInner<K, V, S2>> for LinearMapInner<K, V, S1>
538619
where
539620
K: Eq,
@@ -547,7 +628,7 @@ where
547628
}
548629
}
549630

550-
impl<K, V, S: VecStorage<(K, V)> + ?Sized> Eq for LinearMapInner<K, V, S>
631+
impl<K, V, S: LinearMapStorage<K, V> + ?Sized> Eq for LinearMapInner<K, V, S>
551632
where
552633
K: Eq,
553634
V: PartialEq,

0 commit comments

Comments
 (0)