1use alloc::alloc::Layout;
2use alloc::boxed::Box;
3use alloc::string::String;
4use alloc::vec::Vec;
5use core::cmp::Ordering;
6use core::iter::{ExactSizeIterator, Iterator};
7use core::marker::PhantomData;
8use core::mem::{self, ManuallyDrop};
9use core::ptr::{self, addr_of_mut};
10use core::usize;
11
12use super::{Arc, ArcInner};
13
14#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
17#[repr(C)]
18pub struct HeaderSlice<H, T: ?Sized> {
19 pub header: H,
21
22 pub slice: T,
24}
25
26impl<H, T> Arc<HeaderSlice<H, [T]>> {
27 pub fn from_header_and_iter<I>(header: H, mut items: I) -> Self
30 where
31 I: Iterator<Item = T> + ExactSizeIterator,
32 {
33 assert_ne!(mem::size_of::<T>(), 0, "Need to think about ZST");
34
35 let num_items = items.len();
36
37 let inner = Arc::allocate_for_header_and_slice(num_items);
38
39 unsafe {
40 ptr::write(&mut ((*inner.as_ptr()).data.header), header);
45 let mut current = (*inner.as_ptr()).data.slice.as_mut_ptr();
46 for _ in 0..num_items {
47 ptr::write(
48 current,
49 items
50 .next()
51 .expect("ExactSizeIterator over-reported length"),
52 );
53 current = current.offset(1);
54 }
55 assert!(
56 items.next().is_none(),
57 "ExactSizeIterator under-reported length"
58 );
59 }
60
61 Arc {
63 p: inner,
64 phantom: PhantomData,
65 }
66 }
67
68 pub fn from_header_and_slice(header: H, items: &[T]) -> Self
71 where
72 T: Copy,
73 {
74 assert_ne!(mem::size_of::<T>(), 0, "Need to think about ZST");
75
76 let num_items = items.len();
77
78 let inner = Arc::allocate_for_header_and_slice(num_items);
79
80 unsafe {
81 ptr::write(&mut ((*inner.as_ptr()).data.header), header);
83 let dst = (*inner.as_ptr()).data.slice.as_mut_ptr();
84 ptr::copy_nonoverlapping(items.as_ptr(), dst, num_items);
85 }
86
87 Arc {
89 p: inner,
90 phantom: PhantomData,
91 }
92 }
93
94 pub fn from_header_and_vec(header: H, mut v: Vec<T>) -> Self {
97 let len = v.len();
98
99 let inner = Arc::allocate_for_header_and_slice(len);
100
101 unsafe {
102 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
104
105 ptr::write(dst, header);
107 }
108
109 unsafe {
110 let src = v.as_mut_ptr();
111
112 let dst = addr_of_mut!((*inner.as_ptr()).data.slice) as *mut T;
114
115 ptr::copy_nonoverlapping(src, dst, len);
120
121 v.set_len(0);
125 }
126
127 Arc {
129 p: inner,
130 phantom: PhantomData,
131 }
132 }
133}
134
135impl<H> Arc<HeaderSlice<H, str>> {
136 pub fn from_header_and_str(header: H, string: &str) -> Self {
139 let bytes = Arc::from_header_and_slice(header, string.as_bytes());
140
141 unsafe { Arc::from_raw_inner(Arc::into_raw_inner(bytes) as _) }
146 }
147}
148
149#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
152#[repr(C)]
153pub struct HeaderWithLength<H> {
154 pub header: H,
156
157 pub length: usize,
159}
160
161impl<H> HeaderWithLength<H> {
162 #[inline]
164 pub fn new(header: H, length: usize) -> Self {
165 HeaderWithLength { header, length }
166 }
167}
168
169impl<T: ?Sized> From<Arc<HeaderSlice<(), T>>> for Arc<T> {
170 fn from(this: Arc<HeaderSlice<(), T>>) -> Self {
171 debug_assert_eq!(
172 Layout::for_value::<HeaderSlice<(), T>>(&this),
173 Layout::for_value::<T>(&this.slice)
174 );
175
176 unsafe { Arc::from_raw_inner(Arc::into_raw_inner(this) as _) }
178 }
179}
180
181impl<T: ?Sized> From<Arc<T>> for Arc<HeaderSlice<(), T>> {
182 fn from(this: Arc<T>) -> Self {
183 unsafe { Arc::from_raw_inner(Arc::into_raw_inner(this) as _) }
185 }
186}
187
188impl<T: Copy> From<&[T]> for Arc<[T]> {
189 fn from(slice: &[T]) -> Self {
190 Arc::from_header_and_slice((), slice).into()
191 }
192}
193
194impl From<&str> for Arc<str> {
195 fn from(s: &str) -> Self {
196 Arc::from_header_and_str((), s).into()
197 }
198}
199
200impl From<String> for Arc<str> {
201 fn from(s: String) -> Self {
202 Self::from(&s[..])
203 }
204}
205
206impl<T> From<Box<T>> for Arc<T> {
210 fn from(b: Box<T>) -> Self {
211 let layout = Layout::for_value::<T>(&b);
212
213 let inner = unsafe { Self::allocate_for_layout(layout, |mem| mem as *mut ArcInner<T>) };
215
216 unsafe {
217 let src = Box::into_raw(b);
218
219 let dst = addr_of_mut!((*inner.as_ptr()).data);
221
222 ptr::copy_nonoverlapping(src, dst, 1);
227
228 drop(Box::<ManuallyDrop<T>>::from_raw(src as _));
234 }
235
236 Arc {
237 p: inner,
238 phantom: PhantomData,
239 }
240 }
241}
242
243impl<T> From<Vec<T>> for Arc<[T]> {
244 fn from(v: Vec<T>) -> Self {
245 Arc::from_header_and_vec((), v).into()
246 }
247}
248
249pub(crate) type HeaderSliceWithLength<H, T> = HeaderSlice<HeaderWithLength<H>, T>;
250
251impl<H: PartialOrd, T: ?Sized + PartialOrd> PartialOrd for HeaderSliceWithLength<H, T> {
252 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
253 (&self.header.header, &self.slice).partial_cmp(&(&other.header.header, &other.slice))
254 }
255}
256
257impl<H: Ord, T: ?Sized + Ord> Ord for HeaderSliceWithLength<H, T> {
258 fn cmp(&self, other: &Self) -> Ordering {
259 (&self.header.header, &self.slice).cmp(&(&other.header.header, &other.slice))
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use alloc::boxed::Box;
266 use alloc::string::String;
267 use alloc::vec;
268 use core::iter;
269
270 use crate::{Arc, HeaderSlice};
271
272 #[test]
273 fn from_header_and_iter_smoke() {
274 let arc = Arc::from_header_and_iter(
275 (42u32, 17u8),
276 IntoIterator::into_iter([1u16, 2, 3, 4, 5, 6, 7]),
277 );
278
279 assert_eq!(arc.header, (42, 17));
280 assert_eq!(arc.slice, [1, 2, 3, 4, 5, 6, 7]);
281 }
282
283 #[test]
284 fn from_header_and_slice_smoke() {
285 let arc = Arc::from_header_and_slice((42u32, 17u8), &[1u16, 2, 3, 4, 5, 6, 7]);
286
287 assert_eq!(arc.header, (42, 17));
288 assert_eq!(arc.slice, [1u16, 2, 3, 4, 5, 6, 7]);
289 }
290
291 #[test]
292 fn from_header_and_vec_smoke() {
293 let arc = Arc::from_header_and_vec((42u32, 17u8), vec![1u16, 2, 3, 4, 5, 6, 7]);
294
295 assert_eq!(arc.header, (42, 17));
296 assert_eq!(arc.slice, [1u16, 2, 3, 4, 5, 6, 7]);
297 }
298
299 #[test]
300 fn from_header_and_iter_empty() {
301 let arc = Arc::from_header_and_iter((42u32, 17u8), iter::empty::<u16>());
302
303 assert_eq!(arc.header, (42, 17));
304 assert_eq!(arc.slice, []);
305 }
306
307 #[test]
308 fn from_header_and_slice_empty() {
309 let arc = Arc::from_header_and_slice((42u32, 17u8), &[1u16; 0]);
310
311 assert_eq!(arc.header, (42, 17));
312 assert_eq!(arc.slice, []);
313 }
314
315 #[test]
316 fn from_header_and_vec_empty() {
317 let arc = Arc::from_header_and_vec((42u32, 17u8), vec![1u16; 0]);
318
319 assert_eq!(arc.header, (42, 17));
320 assert_eq!(arc.slice, []);
321 }
322
323 #[test]
324 fn issue_13_empty() {
325 crate::Arc::from_header_and_iter((), iter::empty::<usize>());
326 }
327
328 #[test]
329 fn issue_13_consumption() {
330 let s: &[u8] = &[0u8; 255];
331 crate::Arc::from_header_and_iter((), s.iter().copied());
332 }
333
334 #[test]
335 fn from_header_and_str_smoke() {
336 let a = Arc::from_header_and_str(
337 42,
338 "The answer to the ultimate question of life, the universe, and everything",
339 );
340 assert_eq!(a.header, 42);
341 assert_eq!(
342 &a.slice,
343 "The answer to the ultimate question of life, the universe, and everything"
344 );
345
346 let empty = Arc::from_header_and_str((), "");
347 assert_eq!(empty.header, ());
348 assert_eq!(&empty.slice, "");
349 }
350
351 #[test]
352 fn erase_and_create_from_thin_air_header() {
353 let a: Arc<HeaderSlice<(), [u32]>> = Arc::from_header_and_slice((), &[12, 17, 16]);
354 let b: Arc<[u32]> = a.into();
355
356 assert_eq!(&*b, [12, 17, 16]);
357
358 let c: Arc<HeaderSlice<(), [u32]>> = b.into();
359
360 assert_eq!(&c.slice, [12, 17, 16]);
361 assert_eq!(c.header, ());
362 }
363
364 #[test]
365 fn from_box_and_vec() {
366 let b = Box::new(String::from("xxx"));
367 let b = Arc::<String>::from(b);
368 assert_eq!(&*b, "xxx");
369
370 let v = vec![String::from("1"), String::from("2"), String::from("3")];
371 let v = Arc::<[_]>::from(v);
372 assert_eq!(
373 &*v,
374 [String::from("1"), String::from("2"), String::from("3")]
375 );
376
377 let mut v = vec![String::from("1"), String::from("2"), String::from("3")];
378 v.reserve(10);
379 let v = Arc::<[_]>::from(v);
380 assert_eq!(
381 &*v,
382 [String::from("1"), String::from("2"), String::from("3")]
383 );
384 }
385
386 #[test]
391 fn dst_and_make_mut() {
392 struct MyArc<T: ?Sized>(Arc<HeaderSlice<MyHeader, T>>);
393
394 #[derive(Clone)]
395 struct MyHeader {
396 }
398
399 let dst: MyArc<str> = MyArc(Arc::from_header_and_str(MyHeader {}, "example"));
401 assert_eq!(&dst.0.slice, "example");
402
403 let mut answer: MyArc<u32> = MyArc(Arc::new(HeaderSlice {
405 header: MyHeader {},
406 slice: 6 * 9,
410 }));
411 let mut_ref = Arc::make_mut(&mut answer.0);
412 mut_ref.slice = 42;
413 }
414}