bitcoin_internals/
array_vec.rs1use core::fmt;
6
7pub use safety_boundary::ArrayVec;
8
9mod safety_boundary {
13 use core::mem::MaybeUninit;
14
15 use crate::const_tools::cond_const;
16
17 #[derive(Copy)]
19 pub struct ArrayVec<T: Copy, const CAP: usize> {
20 len: usize,
21 data: [MaybeUninit<T>; CAP],
22 }
23
24 impl<T: Copy, const CAP: usize> ArrayVec<T, CAP> {
25 pub const fn new() -> Self { Self { len: 0, data: [MaybeUninit::uninit(); CAP] } }
27
28 pub const fn from_slice(slice: &[T]) -> Self {
34 assert!(slice.len() <= CAP);
35 let mut data = [MaybeUninit::uninit(); CAP];
36 let mut i = 0;
37 while i < slice.len() {
39 data[i] = MaybeUninit::new(slice[i]);
40 i += 1;
41 }
42
43 Self { len: slice.len(), data }
44 }
45
46 cond_const! {
48 pub const(in 1.64) fn as_slice(&self) -> &[T] {
50 let ptr = &self.data as *const _ as *const T;
51 unsafe { core::slice::from_raw_parts(ptr, self.len) }
52 }
53 }
54
55 pub fn as_mut_slice(&mut self) -> &mut [T] {
57 unsafe { &mut *(&mut self.data[..self.len] as *mut _ as *mut [T]) }
58 }
59
60 pub fn push(&mut self, element: T) {
66 assert!(self.len < CAP);
67 self.data[self.len] = MaybeUninit::new(element);
68 self.len += 1;
69 }
70
71 pub fn extend_from_slice(&mut self, slice: &[T]) {
77 let new_len = self.len.checked_add(slice.len()).expect("integer/buffer overflow");
78 assert!(new_len <= CAP, "buffer overflow");
79 let slice = unsafe { &*(slice as *const _ as *const [MaybeUninit<T>]) };
81 self.data[self.len..new_len].copy_from_slice(slice);
82 self.len = new_len;
83 }
84 }
85}
86
87impl<T: Copy, const CAP: usize> Default for ArrayVec<T, CAP> {
88 fn default() -> Self { Self::new() }
89}
90
91#[allow(clippy::non_canonical_clone_impl)]
96impl<T: Copy, const CAP: usize> Clone for ArrayVec<T, CAP> {
97 fn clone(&self) -> Self { Self::from_slice(self) }
98}
99
100impl<T: Copy, const CAP: usize> core::ops::Deref for ArrayVec<T, CAP> {
101 type Target = [T];
102
103 fn deref(&self) -> &Self::Target { self.as_slice() }
104}
105
106impl<T: Copy, const CAP: usize> core::ops::DerefMut for ArrayVec<T, CAP> {
107 fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() }
108}
109
110impl<T: Copy + Eq, const CAP: usize> Eq for ArrayVec<T, CAP> {}
111
112impl<T: Copy + PartialEq, const CAP1: usize, const CAP2: usize> PartialEq<ArrayVec<T, CAP2>>
113 for ArrayVec<T, CAP1>
114{
115 fn eq(&self, other: &ArrayVec<T, CAP2>) -> bool { **self == **other }
116}
117
118impl<T: Copy + PartialEq, const CAP: usize> PartialEq<[T]> for ArrayVec<T, CAP> {
119 fn eq(&self, other: &[T]) -> bool { **self == *other }
120}
121
122impl<T: Copy + PartialEq, const CAP: usize> PartialEq<ArrayVec<T, CAP>> for [T] {
123 fn eq(&self, other: &ArrayVec<T, CAP>) -> bool { *self == **other }
124}
125
126impl<T: Copy + PartialEq, const CAP: usize, const LEN: usize> PartialEq<[T; LEN]>
127 for ArrayVec<T, CAP>
128{
129 fn eq(&self, other: &[T; LEN]) -> bool { **self == *other }
130}
131
132impl<T: Copy + PartialEq, const CAP: usize, const LEN: usize> PartialEq<ArrayVec<T, CAP>>
133 for [T; LEN]
134{
135 fn eq(&self, other: &ArrayVec<T, CAP>) -> bool { *self == **other }
136}
137
138impl<T: Copy + Ord, const CAP: usize> Ord for ArrayVec<T, CAP> {
139 fn cmp(&self, other: &ArrayVec<T, CAP>) -> core::cmp::Ordering { (**self).cmp(&**other) }
140}
141
142impl<T: Copy + PartialOrd, const CAP1: usize, const CAP2: usize> PartialOrd<ArrayVec<T, CAP2>>
143 for ArrayVec<T, CAP1>
144{
145 fn partial_cmp(&self, other: &ArrayVec<T, CAP2>) -> Option<core::cmp::Ordering> {
146 (**self).partial_cmp(&**other)
147 }
148}
149
150impl<T: Copy + fmt::Debug, const CAP: usize> fmt::Debug for ArrayVec<T, CAP> {
151 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, f) }
152}
153
154impl<T: Copy + core::hash::Hash, const CAP: usize> core::hash::Hash for ArrayVec<T, CAP> {
155 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { core::hash::Hash::hash(&**self, state) }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::ArrayVec;
161
162 #[test]
163 fn arrayvec_ops() {
164 let mut av = ArrayVec::<_, 1>::new();
165 assert!(av.is_empty());
166 av.push(42);
167 assert_eq!(av.len(), 1);
168 assert_eq!(av, [42]);
169 }
170
171 #[test]
172 #[should_panic]
173 fn overflow_push() {
174 let mut av = ArrayVec::<_, 0>::new();
175 av.push(42);
176 }
177
178 #[test]
179 #[should_panic]
180 fn overflow_extend() {
181 let mut av = ArrayVec::<_, 0>::new();
182 av.extend_from_slice(&[42]);
183 }
184
185 #[test]
186 fn extend_from_slice() {
187 let mut av = ArrayVec::<u8, 8>::new();
188 av.extend_from_slice(b"abc");
189 }
190}