arc_slice/slice.rs
1use alloc::{boxed::Box, string::String, vec::Vec};
2use core::{
3 any::Any,
4 borrow::Borrow,
5 cmp,
6 convert::Infallible,
7 fmt,
8 hash::{Hash, Hasher},
9 marker::PhantomData,
10 mem,
11 mem::{ManuallyDrop, MaybeUninit},
12 ops::{Deref, RangeBounds},
13 ptr::NonNull,
14};
15
16#[cfg(feature = "raw-buffer")]
17use crate::buffer::RawBuffer;
18#[cfg(not(feature = "oom-handling"))]
19use crate::layout::{
20 ArcLayout, BoxedSliceLayout, CloneNoAllocLayout, TruncateNoAllocLayout, VecLayout,
21};
22#[allow(unused_imports)]
23use crate::msrv::{ptr, ConstPtrExt, NonNullExt, StrictProvenance};
24use crate::{
25 arc::Arc,
26 buffer::{
27 BorrowMetadata, Buffer, BufferExt, BufferMut, BufferWithMetadata, DynBuffer, Emptyable,
28 Slice, SliceExt, Subsliceable,
29 },
30 error::{AllocError, AllocErrorImpl},
31 layout::{AnyBufferLayout, DefaultLayout, FromLayout, Layout, LayoutMut, StaticLayout},
32 macros::is,
33 slice_mut::{ArcSliceMutLayout, Data},
34 utils::{
35 debug_slice, lower_hex, panic_out_of_range, range_offset_len, subslice_offset_len,
36 transmute_checked, try_transmute, upper_hex, UnwrapChecked, UnwrapInfallible,
37 },
38 ArcSliceMut,
39};
40
41mod arc;
42#[cfg(feature = "raw-buffer")]
43mod raw;
44mod vec;
45
46#[allow(clippy::missing_safety_doc)]
47pub unsafe trait ArcSliceLayout: 'static {
48 type Data;
49 const ANY_BUFFER: bool;
50 const STATIC_DATA: Option<Self::Data>;
51 // MSRV 1.83 const `Option::unwrap`
52 const STATIC_DATA_UNCHECKED: MaybeUninit<Self::Data>;
53 fn data_from_arc<S: Slice + ?Sized, const ANY_BUFFER: bool>(
54 arc: Arc<S, ANY_BUFFER>,
55 ) -> Self::Data;
56 fn data_from_arc_slice<S: Slice + ?Sized>(arc: Arc<S, false>) -> Self::Data {
57 Self::data_from_arc(arc)
58 }
59 fn data_from_arc_buffer<S: Slice + ?Sized, const ANY_BUFFER: bool, B: DynBuffer + Buffer<S>>(
60 arc: Arc<S, ANY_BUFFER>,
61 ) -> Self::Data {
62 Self::data_from_arc(arc)
63 }
64 fn try_data_from_arc<S: Slice + ?Sized, const ANY_BUFFER: bool>(
65 arc: ManuallyDrop<Arc<S, ANY_BUFFER>>,
66 ) -> Option<Self::Data> {
67 Some(Self::data_from_arc(ManuallyDrop::into_inner(arc)))
68 }
69 fn data_from_static<S: Slice + ?Sized, E: AllocErrorImpl>(
70 _slice: &'static S,
71 ) -> Result<Self::Data, (E, &'static S)> {
72 Ok(Self::STATIC_DATA.unwrap())
73 }
74 fn data_from_vec<S: Slice + ?Sized, E: AllocErrorImpl>(
75 vec: S::Vec,
76 ) -> Result<Self::Data, (E, S::Vec)>;
77 #[cfg(feature = "raw-buffer")]
78 fn data_from_raw_buffer<S: Slice + ?Sized, B: DynBuffer + RawBuffer<S>>(
79 _buffer: *const (),
80 ) -> Option<Self::Data> {
81 None
82 }
83 fn clone<S: Slice + ?Sized, E: AllocErrorImpl>(
84 start: NonNull<S::Item>,
85 length: usize,
86 data: &Self::Data,
87 ) -> Result<Self::Data, E>;
88 unsafe fn drop<S: Slice + ?Sized, const UNIQUE_HINT: bool>(
89 start: NonNull<S::Item>,
90 length: usize,
91 data: &mut ManuallyDrop<Self::Data>,
92 );
93 fn borrowed_data<S: Slice + ?Sized>(_data: &Self::Data) -> Option<*const ()> {
94 None
95 }
96 fn clone_borrowed_data<S: Slice + ?Sized>(_ptr: *const ()) -> Option<Self::Data> {
97 None
98 }
99 fn truncate<S: Slice + ?Sized, E: AllocErrorImpl>(
100 _start: NonNull<S::Item>,
101 _length: usize,
102 _data: &mut Self::Data,
103 ) -> Result<(), E> {
104 Ok(())
105 }
106 fn is_unique<S: Slice + ?Sized>(data: &Self::Data) -> bool;
107 fn get_metadata<S: Slice + ?Sized, M: Any>(data: &Self::Data) -> Option<&M>;
108 unsafe fn take_buffer<S: Slice + ?Sized, B: Buffer<S>>(
109 start: NonNull<S::Item>,
110 length: usize,
111 data: &mut ManuallyDrop<Self::Data>,
112 ) -> Option<B>;
113 unsafe fn take_array<T: Send + Sync + 'static, const N: usize>(
114 start: NonNull<T>,
115 length: usize,
116 data: &mut ManuallyDrop<Self::Data>,
117 ) -> Option<[T; N]>;
118 unsafe fn mut_data<S: Slice + ?Sized, L: ArcSliceMutLayout>(
119 start: NonNull<S::Item>,
120 length: usize,
121 data: &mut ManuallyDrop<Self::Data>,
122 ) -> Option<(usize, Option<Data>)>;
123 fn update_layout<S: Slice + ?Sized, L: ArcSliceLayout, E: AllocErrorImpl>(
124 start: NonNull<S::Item>,
125 length: usize,
126 data: Self::Data,
127 ) -> Option<L::Data>;
128}
129
130/// A thread-safe, cheaply cloneable and sliceable container.
131///
132/// `ArcSlice<S>` is roughly equivalent to a `(*const S, Arc<S>)` pair: a pointer into a shared
133/// buffer and its associated reference-counted owner. This allows it to behave like a slice while
134/// ensuring memory safety and shared ownership.
135/// <br>
136/// With the appropriate [layout], `ArcSlice` can wrap arbitrary buffers such as Vec, memory-mapped
137/// files, etc. Arbitrary metadata can also be attached to the buffer for contextual or
138/// domain-specific needs.
139///
140/// It is mainly intended to manipulate `[u8]`/`str` byte slices, to facilitate zero-copy
141/// operations in network programming, hence the aliases [`ArcBytes`]/[`ArcStr`]. But it can
142/// actually handle any type of slices, from strings with specific invariants to primitive slices
143/// with droppable items.
144///
145/// # Examples
146///
147/// ```rust
148/// use arc_slice::ArcSlice;
149///
150/// let mut mem = ArcSlice::<[u8]>::from(b"hello world");
151/// let a = mem.subslice(0..5);
152///
153/// assert_eq!(a, b"hello");
154///
155/// let b = mem.split_to(6);
156///
157/// assert_eq!(mem, b"world");
158/// assert_eq!(b, b"hello ");
159/// ```
160///
161/// With shared memory:
162/// ```rust
163/// use std::{
164/// fs::File,
165/// path::{Path, PathBuf},
166/// };
167///
168/// use arc_slice::{buffer::AsRefBuffer, layout::ArcLayout, ArcSlice};
169/// use memmap2::Mmap;
170///
171/// # fn main() -> std::io::Result<()> {
172/// let path = Path::new("README.md").to_owned();
173/// # #[cfg(not(miri))]
174/// let file = File::open(&path)?;
175/// # #[cfg(not(miri))]
176/// let mmap = unsafe { Mmap::map(&file)? };
177/// # #[cfg(miri)]
178/// # let mmap = b"# arc-slice".to_vec();
179///
180/// let buffer = AsRefBuffer(mmap);
181/// let bytes: ArcSlice<[u8], ArcLayout<true>> = ArcSlice::from_buffer_with_metadata(buffer, path);
182/// assert!(bytes.starts_with(b"# arc-slice"));
183/// assert_eq!(bytes.metadata::<PathBuf>().unwrap(), Path::new("README.md"));
184/// # Ok(())
185/// # }
186/// ```
187///
188/// [layout]: crate::layout
189/// [`ArcBytes`]: crate::ArcBytes
190/// [`ArcStr`]: crate::ArcStr
191#[cfg_attr(feature = "inlined", repr(C))]
192pub struct ArcSlice<S: Slice + ?Sized, L: Layout = DefaultLayout> {
193 #[cfg(not(feature = "inlined"))]
194 pub(crate) start: NonNull<S::Item>,
195 #[cfg(not(feature = "inlined"))]
196 pub(crate) length: usize,
197 #[cfg(not(feature = "inlined"))]
198 data: ManuallyDrop<<L as ArcSliceLayout>::Data>,
199 #[cfg(all(target_endian = "big", feature = "inlined"))]
200 pub(crate) length: usize,
201 #[cfg(feature = "inlined")]
202 data: ManuallyDrop<<L as ArcSliceLayout>::Data>,
203 #[cfg(feature = "inlined")]
204 pub(crate) start: NonNull<S::Item>,
205 #[cfg(all(target_endian = "little", feature = "inlined"))]
206 pub(crate) length: usize,
207}
208
209unsafe impl<S: Slice + ?Sized, L: Layout> Send for ArcSlice<S, L> {}
210unsafe impl<S: Slice + ?Sized, L: Layout> Sync for ArcSlice<S, L> {}
211
212impl<S: Slice + ?Sized, L: Layout> ArcSlice<S, L> {
213 pub(crate) const fn init(
214 start: NonNull<S::Item>,
215 length: usize,
216 data: <L as ArcSliceLayout>::Data,
217 ) -> Self {
218 Self {
219 start,
220 length,
221 data: ManuallyDrop::new(data),
222 }
223 }
224
225 /// Creates a new empty `ArcSlice`.
226 ///
227 /// This operation doesn't allocate; it is roughly equivalent to `ArcSlice::from_static(&[])`.
228 ///
229 /// # Examples
230 ///
231 /// ```rust
232 /// use arc_slice::{layout::ArcLayout, ArcSlice};
233 ///
234 /// let s = ArcSlice::<[u8], ArcLayout<true, true>>::new();
235 /// assert_eq!(s, []);
236 /// ```
237 pub const fn new() -> Self
238 where
239 S: Emptyable,
240 L: StaticLayout,
241 {
242 let data = unsafe { L::STATIC_DATA_UNCHECKED.assume_init() };
243 Self::init(NonNull::dangling(), 0, data)
244 }
245
246 fn from_slice_impl<E: AllocErrorImpl>(slice: &S) -> Result<Self, E>
247 where
248 S::Item: Copy,
249 {
250 let (start, length) = slice.to_raw_parts();
251 if let Some(empty) = ArcSlice::new_empty(start, length) {
252 return Ok(empty);
253 }
254 let (arc, start) = Arc::<S, false>::new(slice)?;
255 Ok(Self::init(start, slice.len(), L::data_from_arc_slice(arc)))
256 }
257
258 /// Creates a new `ArcSlice` by copying the given slice.
259 ///
260 /// # Panics
261 ///
262 /// Panics if the new capacity exceeds `isize::MAX - size_of::<usize>()` bytes.
263 ///
264 /// # Examples
265 ///
266 /// ```rust
267 /// use arc_slice::ArcSlice;
268 ///
269 /// let s = ArcSlice::<[u8]>::from_slice(b"hello world");
270 /// assert_eq!(s, b"hello world");
271 /// ```
272 #[cfg(feature = "oom-handling")]
273 pub fn from_slice(slice: &S) -> Self
274 where
275 S::Item: Copy,
276 {
277 Self::from_slice_impl::<Infallible>(slice).unwrap_infallible()
278 }
279
280 /// Tries creating a new `ArcSlice` by copying the given slice, returning an error if the
281 /// allocation fails.
282 ///
283 /// # Examples
284 ///
285 /// ```rust
286 /// use arc_slice::ArcSlice;
287 ///
288 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
289 /// let s = ArcSlice::<[u8]>::try_from_slice(b"hello world")?;
290 /// assert_eq!(s, b"hello world");
291 /// # Ok(())
292 /// # }
293 /// ```
294 pub fn try_from_slice(slice: &S) -> Result<Self, AllocError>
295 where
296 S::Item: Copy,
297 {
298 Self::from_slice_impl::<AllocError>(slice)
299 }
300
301 fn from_array_impl<E: AllocErrorImpl, const N: usize>(
302 array: [S::Item; N],
303 ) -> Result<Self, (E, [S::Item; N])> {
304 if let Some(empty) = Self::new_empty(NonNull::dangling(), N) {
305 return Ok(empty);
306 }
307 let (arc, start) = Arc::<S, false>::new_array::<E, N>(array)?;
308 Ok(Self::init(start, N, L::data_from_arc_slice(arc)))
309 }
310
311 #[cfg(feature = "serde")]
312 pub(crate) fn new_bytes(slice: &S) -> Self {
313 let (start, length) = slice.to_raw_parts();
314 if let Some(empty) = ArcSlice::new_empty(start, length) {
315 return empty;
316 }
317 let (arc, start) = unsafe {
318 Arc::<S, false>::new_unchecked::<Infallible>(slice.to_slice()).unwrap_infallible()
319 };
320 Self::init(start, slice.len(), L::data_from_arc_slice(arc))
321 }
322
323 #[cfg(feature = "serde")]
324 pub(crate) fn new_byte_vec(vec: S::Vec) -> Self {
325 if !L::ANY_BUFFER {
326 return Self::new_bytes(ManuallyDrop::new(vec).as_slice());
327 }
328 Self::from_vec(vec)
329 }
330
331 pub(crate) fn from_vec_impl<E: AllocErrorImpl>(mut vec: S::Vec) -> Result<Self, (E, S::Vec)> {
332 if vec.capacity() == 0 {
333 return Self::from_array_impl::<E, 0>([]).map_err(|(err, _)| (err, vec));
334 }
335 let start = S::vec_start(&mut vec);
336 Ok(Self::init(start, vec.len(), L::data_from_vec::<S, E>(vec)?))
337 }
338
339 pub(crate) fn from_vec(vec: S::Vec) -> Self {
340 Self::from_vec_impl::<Infallible>(vec).unwrap_infallible()
341 }
342
343 fn new_empty(start: NonNull<S::Item>, length: usize) -> Option<Self> {
344 let data = L::STATIC_DATA.filter(|_| length == 0)?;
345 Some(Self::init(start, length, data))
346 }
347
348 /// Returns the number of items in the slice.
349 ///
350 /// # Examples
351 ///
352 /// ```rust
353 /// use arc_slice::ArcSlice;
354 ///
355 /// let s = ArcSlice::<[u8]>::from(&[0, 1, 2]);
356 /// assert_eq!(s.len(), 3);
357 /// ```
358 pub const fn len(&self) -> usize {
359 self.length
360 }
361
362 /// Returns `true` if the slice contains no items.
363 ///
364 /// # Examples
365 ///
366 /// ```rust
367 /// use arc_slice::ArcSlice;
368 ///
369 /// let s = ArcSlice::<[u8]>::from(&[0, 1, 2]);
370 /// assert!(!s.is_empty());
371 ///
372 /// let s = ArcSlice::<[u8]>::from(&[]);
373 /// assert!(s.is_empty());
374 /// ```
375 pub const fn is_empty(&self) -> bool {
376 self.len() == 0
377 }
378
379 /// Returns a raw pointer to the slice's first item.
380 ///
381 /// See [`slice::as_ptr`].
382 pub const fn as_ptr(&self) -> *const S::Item {
383 self.start.as_ptr()
384 }
385
386 /// Returns a reference to the underlying slice.
387 ///
388 /// Equivalent to `&self[..]`.
389 ///
390 /// # Examples
391 ///
392 /// ```rust
393 /// use arc_slice::ArcSlice;
394 ///
395 /// let s = ArcSlice::<[u8]>::from(b"hello world");
396 /// assert_eq!(s.as_slice(), b"hello world");
397 /// ```
398 pub fn as_slice(&self) -> &S {
399 unsafe { S::from_raw_parts(self.start, self.length) }
400 }
401
402 /// Returns a borrowed view of an `ArcSlice` subslice with a given range.
403 ///
404 /// See [`ArcSliceBorrow`] documentation.
405 ///
406 /// # Examples
407 ///
408 /// ```rust
409 /// use arc_slice::ArcSlice;
410 ///
411 /// let s = ArcSlice::<[u8]>::from(b"hello world");
412 /// let borrow = s.borrow(..5);
413 /// assert_eq!(&borrow[..], b"hello");
414 /// let s2: ArcSlice<[u8]> = borrow.clone_arc();
415 /// ```
416 pub fn borrow(&self, range: impl RangeBounds<usize>) -> ArcSliceBorrow<S, L>
417 where
418 S: Subsliceable,
419 {
420 unsafe { self.borrow_impl(range_offset_len(self.as_slice(), range)) }
421 }
422
423 /// Returns a borrowed view of an `ArcSlice` subslice from a slice reference.
424 ///
425 /// See [`ArcSliceBorrow`] documentation.
426 ///
427 /// # Examples
428 ///
429 /// ```rust
430 /// use arc_slice::ArcSlice;
431 ///
432 /// let s = ArcSlice::<[u8]>::from(b"hello world");
433 /// let hello = &s[..5];
434 /// let borrow = s.borrow_from_ref(hello);
435 /// assert_eq!(&borrow[..], b"hello");
436 /// let s2: ArcSlice<[u8]> = borrow.clone_arc();
437 /// ```
438 pub fn borrow_from_ref(&self, subset: &S) -> ArcSliceBorrow<S, L>
439 where
440 S: Subsliceable,
441 {
442 unsafe { self.borrow_impl(subslice_offset_len(self.as_slice(), subset)) }
443 }
444
445 unsafe fn borrow_impl(&self, (offset, len): (usize, usize)) -> ArcSliceBorrow<S, L>
446 where
447 S: Subsliceable,
448 {
449 ArcSliceBorrow {
450 start: unsafe { self.start.add(offset) },
451 length: len,
452 ptr: L::borrowed_data::<S>(&self.data).unwrap_or_else(|| ptr::from_ref(self).cast()),
453 _phantom: PhantomData,
454 }
455 }
456
457 fn clone_impl<E: AllocErrorImpl>(&self) -> Result<Self, E> {
458 let data = L::clone::<S, E>(self.start, self.length, &self.data)?;
459 Ok(Self::init(self.start, self.length, data))
460 }
461
462 /// Tries cloning the `ArcSlice`, returning an error if an allocation fails.
463 ///
464 /// The operation may allocate. See [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout)
465 /// documentation for cases where it does not.
466 ///
467 /// # Examples
468 ///
469 /// ```rust
470 /// use arc_slice::ArcSlice;
471 ///
472 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
473 /// let s = ArcSlice::<[u8]>::try_from_slice(b"hello world")?;
474 /// let s2 = s.try_clone()?;
475 /// assert_eq!(s2, b"hello world");
476 /// # Ok(())
477 /// # }
478 /// ```
479 pub fn try_clone(&self) -> Result<Self, AllocError> {
480 self.clone_impl::<AllocError>()
481 }
482
483 unsafe fn subslice_impl<E: AllocErrorImpl>(
484 &self,
485 (offset, len): (usize, usize),
486 ) -> Result<Self, E>
487 where
488 S: Subsliceable,
489 {
490 let start = unsafe { self.start.add(offset) };
491 if let Some(empty) = Self::new_empty(start, len) {
492 return Ok(empty);
493 }
494 let mut clone = self.clone_impl::<E>()?;
495 clone.start = start;
496 clone.length = len;
497 Ok(clone)
498 }
499
500 /// Tries extracting a subslice of an `ArcSlice` with a given range, returning an error if an
501 /// allocation fails.
502 ///
503 /// The operation may allocate. See [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout)
504 /// documentation for cases where it does not.
505 ///
506 /// # Examples
507 ///
508 /// ```rust
509 /// use arc_slice::ArcSlice;
510 ///
511 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
512 /// let s = ArcSlice::<[u8]>::try_from_slice(b"hello world")?;
513 /// let s2 = s.try_subslice(..5)?;
514 /// assert_eq!(s2, b"hello");
515 /// # Ok(())
516 /// # }
517 /// ```
518 pub fn try_subslice(&self, range: impl RangeBounds<usize>) -> Result<Self, AllocError>
519 where
520 S: Subsliceable,
521 {
522 unsafe { self.subslice_impl::<AllocError>(range_offset_len(self.as_slice(), range)) }
523 }
524
525 /// Tries extracting a subslice of an `ArcSlice` from a slice reference, returning an error
526 /// if an allocation fails.
527 ///
528 /// The operation may allocate. See [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout)
529 /// documentation for case where it does not.
530 ///
531 /// # Examples
532 ///
533 /// ```rust
534 /// use arc_slice::ArcSlice;
535 ///
536 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
537 /// let s = ArcSlice::<[u8]>::try_from_slice(b"hello world")?;
538 /// let hello = &s[..5];
539 /// let s2 = s.try_subslice_from_ref(hello)?;
540 /// assert_eq!(s2, b"hello");
541 /// # Ok(())
542 /// # }
543 /// ```
544 pub fn try_subslice_from_ref(&self, subset: &S) -> Result<Self, AllocError>
545 where
546 S: Subsliceable,
547 {
548 unsafe { self.subslice_impl::<AllocError>(subslice_offset_len(self.as_slice(), subset)) }
549 }
550
551 /// Advances the start of the slice by `offset` items.
552 ///
553 /// This operation does not touch the underlying buffer.
554 ///
555 /// # Panics
556 ///
557 /// Panics if `offset > self.len()`.
558 ///
559 /// # Examples
560 ///
561 /// ```rust
562 /// use arc_slice::ArcSlice;
563 ///
564 /// let mut s = ArcSlice::<[u8]>::from(b"hello world");
565 /// s.advance(6);
566 /// assert_eq!(s, b"world");
567 /// ```
568 pub fn advance(&mut self, offset: usize)
569 where
570 S: Subsliceable,
571 {
572 if offset > self.length {
573 panic_out_of_range();
574 }
575 unsafe { self.check_advance(offset) };
576 self.start = unsafe { self.start.add(offset) };
577 self.length -= offset;
578 }
579
580 fn truncate_impl<E: AllocErrorImpl>(&mut self, len: usize) -> Result<(), E>
581 where
582 S: Subsliceable,
583 {
584 if len < self.length {
585 unsafe { self.check_truncate(len) };
586 L::truncate::<S, E>(self.start, self.length, &mut self.data)?;
587 self.length = len;
588 }
589 Ok(())
590 }
591
592 /// Tries truncating the slice to the first `len` items, returning an error if an
593 /// allocation fails.
594 ///
595 /// If `len` is greater than the slice length, this has no effect.
596 ///
597 /// The operation may not allocate, see
598 /// [`TruncateNoAllocLayout`](crate::layout::TruncateNoAllocLayout) documentation.
599 ///
600 /// ```rust
601 /// use arc_slice::ArcSlice;
602 ///
603 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
604 /// let mut s = ArcSlice::<[u8]>::from(b"hello world");
605 /// s.try_truncate(5)?;
606 /// assert_eq!(s, b"hello");
607 /// # Ok(())
608 /// }
609 /// ```
610 pub fn try_truncate(&mut self, len: usize) -> Result<(), AllocError>
611 where
612 S: Subsliceable,
613 {
614 self.truncate_impl::<AllocError>(len)
615 }
616
617 fn split_off_impl<E: AllocErrorImpl>(&mut self, at: usize) -> Result<Self, E>
618 where
619 S: Subsliceable,
620 {
621 if at == 0 {
622 return Ok(mem::replace(self, unsafe { self.subslice_impl((0, 0))? }));
623 } else if at == self.length {
624 return unsafe { self.subslice_impl((at, 0)) };
625 } else if at > self.length {
626 panic_out_of_range();
627 }
628 let mut clone = self.clone_impl()?;
629 clone.start = unsafe { clone.start.add(at) };
630 clone.length -= at;
631 self.length = at;
632 Ok(clone)
633 }
634
635 /// Tries splitting the slice into two at the given index, returning an error if an allocation
636 /// fails.
637 ///
638 /// Afterwards `self` contains elements `[0, at)`, and the returned `ArcSlice`
639 /// contains elements `[at, len)`. This operation does not touch the underlying buffer.
640 ///
641 /// The operation may not allocate, see
642 /// [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout) documentation.
643 ///
644 /// # Panics
645 ///
646 /// Panics if `at > self.len()`.
647 ///
648 /// # Examples
649 ///
650 /// ```rust
651 /// use arc_slice::ArcSlice;
652 ///
653 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
654 /// let mut a = ArcSlice::<[u8]>::from(b"hello world");
655 /// let b = a.try_split_off(5)?;
656 ///
657 /// assert_eq!(a, b"hello");
658 /// assert_eq!(b, b" world");
659 /// # Ok(())
660 /// # }
661 /// ```
662 pub fn try_split_off(&mut self, at: usize) -> Result<Self, AllocError>
663 where
664 S: Subsliceable,
665 {
666 self.split_off_impl::<AllocError>(at)
667 }
668
669 fn split_to_impl<E: AllocErrorImpl>(&mut self, at: usize) -> Result<Self, E>
670 where
671 S: Subsliceable,
672 {
673 if at == 0 {
674 return unsafe { self.subslice_impl((0, 0)) };
675 } else if at == self.length {
676 return Ok(mem::replace(self, unsafe {
677 self.subslice_impl((self.len(), 0))?
678 }));
679 } else if at > self.length {
680 panic_out_of_range();
681 }
682 let mut clone = self.clone_impl()?;
683 clone.length = at;
684 self.start = unsafe { self.start.add(at) };
685 self.length -= at;
686 Ok(clone)
687 }
688
689 /// Tries splitting the slice into two at the given index, returning an error if an allocation
690 /// fails.
691 ///
692 /// Afterwards `self` contains elements `[at, len)`, and the returned `ArcSlice`
693 /// contains elements `[0, at)`. This operation does not touch the underlying buffer.
694 ///
695 /// The operation may not allocate, see
696 /// [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout) documentation.
697 ///
698 /// # Panics
699 ///
700 /// Panics if `at > self.len()`.
701 ///
702 /// # Examples
703 ///
704 /// ```rust
705 /// use arc_slice::ArcSlice;
706 ///
707 /// # fn main() -> Result<(), arc_slice::error::AllocError> {
708 /// let mut a = ArcSlice::<[u8]>::from(b"hello world");
709 /// let b = a.try_split_to(5)?;
710 ///
711 /// assert_eq!(a, b" world");
712 /// assert_eq!(b, b"hello");
713 /// # Ok(())
714 /// # }
715 /// ```
716 pub fn try_split_to(&mut self, at: usize) -> Result<Self, AllocError>
717 where
718 S: Subsliceable,
719 {
720 self.split_to_impl::<AllocError>(at)
721 }
722
723 /// Tries to acquire the slice as mutable, returning an [`ArcSliceMut`] on success.
724 ///
725 /// There must be no other reference to the underlying buffer, and this one must be mutable
726 /// for the conversion to succeed. Otherwise, the original slice is returned. An `ArcSlice`
727 /// created from an array/slice or a vector is guaranteed to have a mutable buffer, as well
728 /// as one returned [`ArcSliceMut::freeze`].
729 ///
730 /// The conversion may allocate depending on the given [layouts](crate::layout), but allocation
731 /// errors are caught and the original slice is also returned in this case.
732 ///
733 /// # Examples
734 ///
735 /// ```rust
736 /// use arc_slice::{layout::DefaultLayoutMut, ArcSlice, ArcSliceMut};
737 ///
738 /// let mut a = ArcSlice::<[u8]>::from(b"hello world");
739 /// let b = a.clone();
740 ///
741 /// assert!(b.try_into_mut::<DefaultLayoutMut>().is_err());
742 /// // b has been dropped
743 /// let a_mut: ArcSliceMut<[u8]> = a.try_into_mut().unwrap();
744 /// ```
745 pub fn try_into_mut<L2: LayoutMut>(self) -> Result<ArcSliceMut<S, L2>, Self> {
746 let mut this = ManuallyDrop::new(self);
747 match unsafe { L::mut_data::<S, L2>(this.start, this.length, &mut this.data) } {
748 Some((capacity, data)) => {
749 Ok(ArcSliceMut::init(this.start, this.length, capacity, data))
750 }
751 None => Err(ManuallyDrop::into_inner(this)),
752 }
753 }
754
755 /// Returns `true` if this is the only reference to the underlying buffer, and if this one
756 /// is unique (see [`Buffer::is_unique`]).
757 ///
758 /// # Examples
759 ///
760 /// ```rust
761 /// use arc_slice::ArcSlice;
762 ///
763 /// let s = ArcSlice::<[u8]>::from(b"hello world");
764 /// assert!(s.is_unique());
765 /// let s2 = s.clone();
766 /// assert!(!s.is_unique());
767 /// drop(s2);
768 /// assert!(s.is_unique());
769 /// ```
770 pub fn is_unique(&self) -> bool {
771 L::is_unique::<S>(&self.data)
772 }
773
774 /// Accesses the metadata of the underlying buffer if it can be successfully downcast.
775 ///
776 /// # Examples
777 ///
778 /// ```rust
779 /// use arc_slice::{layout::ArcLayout, ArcSlice};
780 ///
781 /// let metadata = "metadata".to_string();
782 /// let s = ArcSlice::<[u8], ArcLayout<true>>::from_buffer_with_metadata(vec![0, 1, 2], metadata);
783 /// assert_eq!(s.metadata::<String>().unwrap(), "metadata");
784 /// ```
785 pub fn metadata<M: Any>(&self) -> Option<&M> {
786 L::get_metadata::<S, M>(&self.data)
787 }
788
789 /// Tries downcasting the `ArcSlice` to its underlying buffer.
790 ///
791 /// # Examples
792 ///
793 /// ```rust
794 /// use arc_slice::{layout::ArcLayout, ArcSlice};
795 ///
796 /// let s = ArcSlice::<[u8], ArcLayout<true>>::from(vec![0, 1, 2]);
797 /// assert_eq!(s.try_into_buffer::<Vec<u8>>().unwrap(), [0, 1, 2]);
798 /// ```
799 pub fn try_into_buffer<B: Buffer<S>>(self) -> Result<B, Self> {
800 let mut this = ManuallyDrop::new(self);
801 unsafe { L::take_buffer::<S, B>(this.start, this.length, &mut this.data) }
802 .ok_or_else(|| ManuallyDrop::into_inner(this))
803 }
804
805 fn with_layout_impl<L2: Layout, E: AllocErrorImpl>(self) -> Result<ArcSlice<S, L2>, Self> {
806 let mut this = ManuallyDrop::new(self);
807 let data = unsafe { ManuallyDrop::take(&mut this.data) };
808 match L::update_layout::<S, L2, E>(this.start, this.length, data) {
809 Some(data) => Ok(ArcSlice::init(this.start, this.len(), data)),
810 None => Err(ManuallyDrop::into_inner(this)),
811 }
812 }
813
814 /// Tries to replace the layout of the `ArcSlice`, returning the original slice if it fails.
815 ///
816 /// The [layouts](crate::layout) must be compatible for the conversion to succeed, see
817 /// [`FromLayout`].
818 ///
819 /// The conversion may allocate depending on the given [layouts](crate::layout), but allocation
820 /// errors are caught and the original slice is also returned in this case.
821 ///
822 /// # Examples
823 /// ```rust
824 /// use arc_slice::{
825 /// layout::{ArcLayout, BoxedSliceLayout, VecLayout},
826 /// ArcSlice,
827 /// };
828 ///
829 /// let a = ArcSlice::<[u8], BoxedSliceLayout>::from(vec![0, 1, 2]);
830 ///
831 /// let b = a.try_with_layout::<VecLayout>().unwrap();
832 /// assert!(b.try_with_layout::<ArcLayout<false>>().is_err());
833 /// ```
834 pub fn try_with_layout<L2: Layout>(self) -> Result<ArcSlice<S, L2>, Self> {
835 self.with_layout_impl::<L2, AllocError>()
836 }
837
838 /// Converts an `ArcSlice` into a primitive `ArcSlice`.
839 ///
840 /// # Examples
841 ///
842 /// ```rust
843 /// use arc_slice::ArcSlice;
844 ///
845 /// let s = ArcSlice::<str>::from("hello world");
846 /// let bytes: ArcSlice<[u8]> = s.into_arc_slice();
847 /// assert_eq!(bytes, b"hello world");
848 /// ```
849 pub fn into_arc_slice(self) -> ArcSlice<[S::Item], L> {
850 let mut this = ManuallyDrop::new(self);
851 ArcSlice {
852 start: this.start,
853 length: this.length,
854 data: ManuallyDrop::new(unsafe { ManuallyDrop::take(&mut this.data) }),
855 }
856 }
857
858 /// Tries converting an item slice into the given `ArcSlice`.
859 ///
860 /// The conversion uses [`Slice::try_from_slice`].
861 ///
862 /// # Examples
863 ///
864 /// ```rust
865 /// use arc_slice::ArcSlice;
866 ///
867 /// let utf8 = ArcSlice::<[u8]>::from(b"hello world");
868 /// let not_utf8 = ArcSlice::<[u8]>::from(b"\x80\x81");
869 ///
870 /// assert!(ArcSlice::<str>::try_from_arc_slice(utf8).is_ok());
871 /// assert!(ArcSlice::<str>::try_from_arc_slice(not_utf8).is_err());
872 /// ```
873 #[allow(clippy::type_complexity)]
874 pub fn try_from_arc_slice(
875 slice: ArcSlice<[S::Item], L>,
876 ) -> Result<Self, (S::TryFromSliceError, ArcSlice<[S::Item], L>)> {
877 match S::try_from_slice(&slice) {
878 Ok(_) => Ok(unsafe { Self::from_arc_slice_unchecked(slice) }),
879 Err(error) => Err((error, slice)),
880 }
881 }
882
883 /// Converts an item slice into the given `ArcSlice`, without checking the slice validity.
884 ///
885 /// # Safety
886 ///
887 /// The operation has the same contract as [`Slice::from_slice_unchecked`].
888 ///
889 /// # Examples
890 ///
891 /// ```rust
892 /// use arc_slice::ArcSlice;
893 ///
894 /// let utf8 = ArcSlice::<[u8]>::from(b"hello world");
895 ///
896 /// // SAFETY: `utf8` is a valid utf8 string
897 /// let s = unsafe { ArcSlice::<str>::from_arc_slice_unchecked(utf8) };
898 /// assert_eq!(s, "hello world");
899 /// ```
900 pub unsafe fn from_arc_slice_unchecked(slice: ArcSlice<[S::Item], L>) -> Self {
901 debug_assert!(S::try_from_slice(&slice).is_ok());
902 let mut slice = ManuallyDrop::new(slice);
903 Self {
904 start: slice.start,
905 length: slice.length,
906 data: ManuallyDrop::new(unsafe { ManuallyDrop::take(&mut slice.data) }),
907 }
908 }
909
910 /// Drops an `ArcSlice`, hinting that it should be unique.
911 ///
912 /// In case of actual unicity, this method should be a little bit more efficient than a
913 /// conventional drop. Indeed, in the case where an Arc has been allocated, it will first
914 /// check the refcount, and shortcut the atomic fetch-and-sub if the count is one.
915 pub fn drop_with_unique_hint(self) {
916 let mut this = ManuallyDrop::new(self);
917 unsafe { L::drop::<S, true>(this.start, this.length, &mut this.data) };
918 }
919}
920
921impl<T: Send + Sync + 'static, L: Layout> ArcSlice<[T], L> {
922 /// Creates a new `ArcSlice` by moving the given array.
923 ///
924 /// # Panics
925 ///
926 /// Panics if the new capacity exceeds `isize::MAX - size_of::<usize>()` bytes.
927 ///
928 /// # Examples
929 ///
930 /// ```rust
931 /// use arc_slice::ArcSlice;
932 ///
933 /// let s = ArcSlice::<[u8]>::from_array([0, 1, 2]);
934 /// assert_eq!(s, [0, 1, 2]);
935 /// ```
936 #[cfg(feature = "oom-handling")]
937 pub fn from_array<const N: usize>(array: [T; N]) -> Self {
938 Self::from_array_impl::<Infallible, N>(array).unwrap_infallible()
939 }
940
941 /// Tries creating a new `ArcSlice` by moving the given array, returning it if an allocation
942 /// fails.
943 ///
944 /// # Examples
945 ///
946 /// ```rust
947 /// use arc_slice::ArcSlice;
948 ///
949 /// let s = ArcSlice::<[u8]>::try_from_array([0, 1, 2]).unwrap();
950 /// assert_eq!(s, [0, 1, 2]);
951 /// ```
952 pub fn try_from_array<const N: usize>(array: [T; N]) -> Result<Self, [T; N]> {
953 Self::from_array_impl::<AllocError, N>(array).map_err(|(_, array)| array)
954 }
955}
956
957impl<
958 S: Slice + ?Sized,
959 #[cfg(feature = "oom-handling")] L: Layout,
960 #[cfg(not(feature = "oom-handling"))] L: TruncateNoAllocLayout,
961 > ArcSlice<S, L>
962{
963 /// Truncate the slice to the first `len` items.
964 ///
965 /// If `len` is greater than the slice length, this has no effect.
966 ///
967 /// ```rust
968 /// use arc_slice::ArcSlice;
969 ///
970 /// let mut s = ArcSlice::<[u8]>::from(b"hello world");
971 /// s.truncate(5);
972 /// assert_eq!(s, b"hello");
973 /// ```
974 pub fn truncate(&mut self, len: usize)
975 where
976 S: Subsliceable,
977 {
978 self.truncate_impl::<Infallible>(len).unwrap_infallible();
979 }
980}
981
982impl<
983 S: Slice + ?Sized,
984 #[cfg(feature = "oom-handling")] L: Layout,
985 #[cfg(not(feature = "oom-handling"))] L: CloneNoAllocLayout,
986 > ArcSlice<S, L>
987{
988 /// Extracts a subslice of an `ArcSlice` with a given range.
989 ///
990 /// # Examples
991 ///
992 /// ```rust
993 /// use arc_slice::ArcSlice;
994 ///
995 /// let s = ArcSlice::<[u8]>::from(b"hello world");
996 /// let s2 = s.subslice(..5);
997 /// assert_eq!(s2, b"hello");
998 /// ```
999 pub fn subslice(&self, range: impl RangeBounds<usize>) -> Self
1000 where
1001 S: Subsliceable,
1002 {
1003 unsafe { self.subslice_impl::<Infallible>(range_offset_len(self.as_slice(), range)) }
1004 .unwrap_infallible()
1005 }
1006
1007 /// Extracts a subslice of an `ArcSlice` from a slice reference.
1008 ///
1009 /// # Examples
1010 ///
1011 /// ```rust
1012 /// use arc_slice::ArcSlice;
1013 ///
1014 /// let s = ArcSlice::<[u8]>::from(b"hello world");
1015 /// let hello = &s[..5];
1016 /// let s2 = s.subslice_from_ref(hello);
1017 /// assert_eq!(s2, b"hello");
1018 /// ```
1019 pub fn subslice_from_ref(&self, subset: &S) -> Self
1020 where
1021 S: Subsliceable,
1022 {
1023 unsafe { self.subslice_impl::<Infallible>(subslice_offset_len(self.as_slice(), subset)) }
1024 .unwrap_infallible()
1025 }
1026
1027 /// Splits the slice into two at the given index.
1028 ///
1029 /// Afterwards `self` contains elements `[0, at)`, and the returned `ArcSlice`
1030 /// contains elements `[at, len)`. This operation does not touch the underlying buffer.
1031 ///
1032 /// # Panics
1033 ///
1034 /// Panics if `at > self.len()`.
1035 ///
1036 /// # Examples
1037 ///
1038 /// ```rust
1039 /// use arc_slice::ArcSlice;
1040 ///
1041 /// let mut a = ArcSlice::<[u8]>::from(b"hello world");
1042 /// let b = a.split_off(5);
1043 ///
1044 /// assert_eq!(a, b"hello");
1045 /// assert_eq!(b, b" world");
1046 /// ```
1047 #[must_use = "consider `ArcSlice::truncate` if you don't need the other half"]
1048 pub fn split_off(&mut self, at: usize) -> Self
1049 where
1050 S: Subsliceable,
1051 {
1052 self.split_off_impl::<Infallible>(at).unwrap_infallible()
1053 }
1054
1055 /// Splits the slice into two at the given index.
1056 ///
1057 /// Afterwards `self` contains elements `[at, len)`, and the returned `ArcSlice`
1058 /// contains elements `[0, at)`. This operation does not touch the underlying buffer.
1059 ///
1060 /// # Panics
1061 ///
1062 /// Panics if `at > self.len()`.
1063 ///
1064 /// # Examples
1065 ///
1066 /// ```rust
1067 /// use arc_slice::ArcSlice;
1068 ///
1069 /// let mut a = ArcSlice::<[u8]>::from(b"hello world");
1070 /// let b = a.split_to(5);
1071 ///
1072 /// assert_eq!(a, b" world");
1073 /// assert_eq!(b, b"hello");
1074 /// ```
1075 #[must_use = "consider `ArcSlice::advance` if you don't need the other half"]
1076 pub fn split_to(&mut self, at: usize) -> Self
1077 where
1078 S: Subsliceable,
1079 {
1080 self.split_to_impl::<Infallible>(at).unwrap_infallible()
1081 }
1082}
1083
1084#[cfg(feature = "oom-handling")]
1085impl<S: Slice + ?Sized, L: Layout> ArcSlice<S, L> {
1086 /// Replace the layout of the `ArcSlice`.
1087 ///
1088 /// The [layouts](crate::layout) must be compatible, see [`FromLayout`].
1089 ///
1090 /// # Examples
1091 /// ```rust
1092 /// use arc_slice::{
1093 /// layout::{ArcLayout, BoxedSliceLayout, VecLayout},
1094 /// ArcSlice,
1095 /// };
1096 ///
1097 /// let a = ArcSlice::<[u8]>::from(b"hello world");
1098 ///
1099 /// let b = a.with_layout::<VecLayout>();
1100 /// ```
1101 pub fn with_layout<L2: FromLayout<L>>(self) -> ArcSlice<S, L2> {
1102 self.with_layout_impl::<L2, Infallible>().unwrap_checked()
1103 }
1104}
1105
1106#[cfg(not(feature = "oom-handling"))]
1107impl<S: Slice + ?Sized, const ANY_BUFFER: bool, const STATIC: bool>
1108 ArcSlice<S, ArcLayout<ANY_BUFFER, STATIC>>
1109{
1110 /// Replace the layout of the `ArcSlice`.
1111 ///
1112 /// The [layouts](crate::layout) must be compatible, see [`FromLayout`].
1113 ///
1114 /// # Examples
1115 /// ```rust
1116 /// use arc_slice::{
1117 /// layout::{ArcLayout, BoxedSliceLayout, VecLayout},
1118 /// ArcSlice,
1119 /// };
1120 ///
1121 /// let a = ArcSlice::<[u8]>::from(b"hello world");
1122 ///
1123 /// let b = a.with_layout::<VecLayout>();
1124 /// ```
1125 pub fn with_layout<L2: FromLayout<ArcLayout<ANY_BUFFER, STATIC>>>(self) -> ArcSlice<S, L2> {
1126 self.with_layout_impl::<L2, Infallible>().unwrap_checked()
1127 }
1128}
1129
1130impl<S: Slice + ?Sized, L: AnyBufferLayout> ArcSlice<S, L> {
1131 pub(crate) fn from_dyn_buffer_impl<B: DynBuffer + Buffer<S>, E: AllocErrorImpl>(
1132 buffer: B,
1133 ) -> Result<Self, (E, B)> {
1134 let (arc, start, length) = Arc::new_buffer::<_, E>(buffer)?;
1135 let data = L::data_from_arc_buffer::<S, true, B>(arc);
1136 Ok(Self::init(start, length, data))
1137 }
1138
1139 pub(crate) fn from_static_impl<E: AllocErrorImpl>(
1140 slice: &'static S,
1141 ) -> Result<Self, (E, &'static S)> {
1142 let (start, length) = slice.to_raw_parts();
1143 Ok(Self::init(
1144 start,
1145 length,
1146 L::data_from_static::<_, E>(slice)?,
1147 ))
1148 }
1149
1150 fn from_buffer_impl<B: Buffer<S>, E: AllocErrorImpl>(mut buffer: B) -> Result<Self, (E, B)> {
1151 match try_transmute::<B, &'static S>(buffer) {
1152 Ok(slice) => {
1153 return Self::from_static_impl::<E>(slice)
1154 .map_err(|(err, s)| (err, transmute_checked(s)))
1155 }
1156 Err(b) => buffer = b,
1157 }
1158 match try_transmute::<B, Box<S>>(buffer) {
1159 Ok(boxed) => {
1160 let vec = unsafe { S::from_vec_unchecked(boxed.into_boxed_slice().into_vec()) };
1161 return match Self::from_vec_impl::<E>(vec) {
1162 Ok(this) => Ok(this),
1163 Err((err, vec)) => Err((
1164 err,
1165 transmute_checked(unsafe {
1166 S::from_boxed_slice_unchecked(S::into_vec(vec).into_boxed_slice())
1167 }),
1168 )),
1169 };
1170 }
1171 Err(b) => buffer = b,
1172 }
1173 match try_transmute::<B, S::Vec>(buffer) {
1174 Ok(vec) => {
1175 return Self::from_vec_impl::<E>(vec)
1176 .map_err(|(err, v)| (err, transmute_checked(v)))
1177 }
1178 Err(b) => buffer = b,
1179 }
1180 Self::from_dyn_buffer_impl::<_, E>(BufferWithMetadata::new(buffer, ()))
1181 .map_err(|(err, b)| (err, b.buffer()))
1182 }
1183
1184 /// Creates a new `ArcSlice` with the given underlying buffer.
1185 ///
1186 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer).
1187 ///
1188 /// # Examples
1189 ///
1190 /// ```rust
1191 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1192 ///
1193 /// let s = ArcSlice::<[u8], ArcLayout<true>>::from_buffer(vec![0, 1, 2]);
1194 /// assert_eq!(s, [0, 1, 2]);
1195 /// assert_eq!(s.try_into_buffer::<Vec<u8>>().unwrap(), vec![0, 1, 2]);
1196 /// ```
1197 #[cfg(feature = "oom-handling")]
1198 pub fn from_buffer<B: Buffer<S>>(buffer: B) -> Self {
1199 Self::from_buffer_impl::<_, Infallible>(buffer).unwrap_infallible()
1200 }
1201
1202 /// Tries creating a new `ArcSlice` with the given underlying buffer, returning it if an
1203 /// allocation fails.
1204 ///
1205 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer).
1206 ///
1207 /// Having an Arc allocation depends on the [layout](crate::layout) and the buffer type,
1208 /// e.g. there will be no allocation for a `Vec` with [`VecLayout`](crate::layout::VecLayout).
1209 ///
1210 /// # Examples
1211 ///
1212 /// ```rust
1213 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1214 ///
1215 /// let s = ArcSlice::<[u8], ArcLayout<true>>::try_from_buffer(vec![0, 1, 2]).unwrap();
1216 /// assert_eq!(s, [0, 1, 2]);
1217 /// assert_eq!(s.try_into_buffer::<Vec<u8>>().unwrap(), vec![0, 1, 2]);
1218 /// ```
1219 pub fn try_from_buffer<B: Buffer<S>>(buffer: B) -> Result<Self, B> {
1220 Self::from_buffer_impl::<_, AllocError>(buffer).map_err(|(_, buffer)| buffer)
1221 }
1222
1223 fn from_buffer_with_metadata_impl<B: Buffer<S>, M: Send + Sync + 'static, E: AllocErrorImpl>(
1224 buffer: B,
1225 metadata: M,
1226 ) -> Result<Self, (E, (B, M))> {
1227 if is!(M, ()) {
1228 return Self::from_buffer_impl::<_, E>(buffer).map_err(|(err, b)| (err, (b, metadata)));
1229 }
1230 Self::from_dyn_buffer_impl::<_, E>(BufferWithMetadata::new(buffer, metadata))
1231 .map_err(|(err, b)| (err, b.into_tuple()))
1232 }
1233
1234 /// Creates a new `ArcSlice` with the given underlying buffer and its associated metadata.
1235 ///
1236 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1237 /// metadata can be retrieved with [`metadata`](Self::metadata).
1238 ///
1239 /// # Examples
1240 ///
1241 /// ```rust
1242 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1243 ///
1244 /// let metadata = "metadata".to_string();
1245 /// let s = ArcSlice::<[u8], ArcLayout<true>>::from_buffer_with_metadata(vec![0, 1, 2], metadata);
1246 /// assert_eq!(s, [0, 1, 2]);
1247 /// assert_eq!(s.metadata::<String>().unwrap(), "metadata");
1248 /// assert_eq!(s.try_into_buffer::<Vec<u8>>().unwrap(), vec![0, 1, 2]);
1249 /// ```
1250 #[cfg(feature = "oom-handling")]
1251 pub fn from_buffer_with_metadata<B: Buffer<S>, M: Send + Sync + 'static>(
1252 buffer: B,
1253 metadata: M,
1254 ) -> Self {
1255 Self::from_buffer_with_metadata_impl::<_, _, Infallible>(buffer, metadata)
1256 .unwrap_infallible()
1257 }
1258
1259 /// Tries creates a new `ArcSlice` with the given underlying buffer and its associated metadata,
1260 /// returning them if an allocation fails.
1261 ///
1262 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1263 /// metadata can be retrieved with [`metadata`](Self::metadata).
1264 ///
1265 /// Having an Arc allocation depends on the [layout](crate::layout) and the buffer type,
1266 /// e.g. there will be no allocation for a `Vec` with [`VecLayout`](crate::layout::VecLayout).
1267 ///
1268 /// # Examples
1269 ///
1270 /// ```rust
1271 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1272 ///
1273 /// let metadata = "metadata".to_string();
1274 /// let s =
1275 /// ArcSlice::<[u8], ArcLayout<true>>::try_from_buffer_with_metadata(vec![0, 1, 2], metadata)
1276 /// .unwrap();
1277 /// assert_eq!(s, [0, 1, 2]);
1278 /// assert_eq!(s.metadata::<String>().unwrap(), "metadata");
1279 /// assert_eq!(s.try_into_buffer::<Vec<u8>>().unwrap(), vec![0, 1, 2]);
1280 /// ```
1281 pub fn try_from_buffer_with_metadata<B: Buffer<S>, M: Send + Sync + 'static>(
1282 buffer: B,
1283 metadata: M,
1284 ) -> Result<Self, (B, M)> {
1285 Self::from_buffer_with_metadata_impl::<_, _, AllocError>(buffer, metadata)
1286 .map_err(|(_, bm)| bm)
1287 }
1288
1289 /// Creates a new `ArcSlice` with the given underlying buffer with borrowed metadata.
1290 ///
1291 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1292 /// metadata can be retrieved with [`metadata`](Self::metadata).
1293 ///
1294 /// # Examples
1295 ///
1296 /// ```rust
1297 /// use arc_slice::{
1298 /// buffer::{BorrowMetadata, Buffer},
1299 /// layout::ArcLayout,
1300 /// ArcSlice,
1301 /// };
1302 ///
1303 /// #[derive(Debug, PartialEq, Eq)]
1304 /// struct MyBuffer(Vec<u8>);
1305 /// impl Buffer<[u8]> for MyBuffer {
1306 /// fn as_slice(&self) -> &[u8] {
1307 /// &self.0
1308 /// }
1309 /// }
1310 /// #[derive(Debug, PartialEq, Eq)]
1311 /// struct MyMetadata;
1312 /// impl BorrowMetadata for MyBuffer {
1313 /// type Metadata = MyMetadata;
1314 /// fn borrow_metadata(&self) -> &Self::Metadata {
1315 /// &MyMetadata
1316 /// }
1317 /// }
1318 /// let buffer = MyBuffer(vec![0, 1, 2]);
1319 /// let s = ArcSlice::<[u8], ArcLayout<true>>::from_buffer_with_borrowed_metadata(buffer);
1320 /// assert_eq!(s, [0, 1, 2]);
1321 /// assert_eq!(s.metadata::<MyMetadata>().unwrap(), &MyMetadata);
1322 /// assert_eq!(
1323 /// s.try_into_buffer::<MyBuffer>().unwrap(),
1324 /// MyBuffer(vec![0, 1, 2])
1325 /// );
1326 /// ```
1327 #[cfg(feature = "oom-handling")]
1328 pub fn from_buffer_with_borrowed_metadata<B: Buffer<S> + BorrowMetadata>(buffer: B) -> Self {
1329 Self::from_dyn_buffer_impl::<_, Infallible>(buffer).unwrap_infallible()
1330 }
1331
1332 /// Tries creating a new `ArcSlice` with the given underlying buffer with borrowed metadata,
1333 /// returning it if an allocation fails.
1334 ///
1335 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1336 /// metadata can be retrieved with [`metadata`](Self::metadata).
1337 ///
1338 /// Having an Arc allocation depends on the [layout](crate::layout) and the buffer type,
1339 /// e.g. there will be no allocation for a `Vec` with [`VecLayout`](crate::layout::VecLayout).
1340 ///
1341 /// # Examples
1342 ///
1343 /// ```rust
1344 /// use arc_slice::{
1345 /// buffer::{BorrowMetadata, Buffer},
1346 /// layout::ArcLayout,
1347 /// ArcSlice,
1348 /// };
1349 ///
1350 /// #[derive(Debug, PartialEq, Eq)]
1351 /// struct MyBuffer(Vec<u8>);
1352 /// impl Buffer<[u8]> for MyBuffer {
1353 /// fn as_slice(&self) -> &[u8] {
1354 /// &self.0
1355 /// }
1356 /// }
1357 /// #[derive(Debug, PartialEq, Eq)]
1358 /// struct MyMetadata;
1359 /// impl BorrowMetadata for MyBuffer {
1360 /// type Metadata = MyMetadata;
1361 /// fn borrow_metadata(&self) -> &Self::Metadata {
1362 /// &MyMetadata
1363 /// }
1364 /// }
1365 /// let buffer = MyBuffer(vec![0, 1, 2]);
1366 /// let s =
1367 /// ArcSlice::<[u8], ArcLayout<true>>::try_from_buffer_with_borrowed_metadata(buffer).unwrap();
1368 /// assert_eq!(s, [0, 1, 2]);
1369 /// assert_eq!(s.metadata::<MyMetadata>().unwrap(), &MyMetadata);
1370 /// assert_eq!(
1371 /// s.try_into_buffer::<MyBuffer>().unwrap(),
1372 /// MyBuffer(vec![0, 1, 2])
1373 /// );
1374 /// ```
1375 pub fn try_from_buffer_with_borrowed_metadata<B: Buffer<S> + BorrowMetadata>(
1376 buffer: B,
1377 ) -> Result<Self, B> {
1378 Self::from_dyn_buffer_impl::<_, AllocError>(buffer).map_err(|(_, buffer)| buffer)
1379 }
1380
1381 #[cfg(feature = "raw-buffer")]
1382 fn from_raw_buffer_impl<B: DynBuffer + RawBuffer<S>, E: AllocErrorImpl>(
1383 buffer: B,
1384 ) -> Result<Self, (E, B)> {
1385 let ptr = buffer.into_raw();
1386 if let Some(data) = L::data_from_raw_buffer::<S, B>(ptr) {
1387 let buffer = ManuallyDrop::new(unsafe { B::from_raw(ptr) });
1388 let (start, length) = buffer.as_slice().to_raw_parts();
1389 return Ok(Self::init(start, length, data));
1390 }
1391 Self::from_dyn_buffer_impl::<_, E>(unsafe { B::from_raw(ptr) })
1392 }
1393
1394 /// Creates a new `ArcSlice` with the given underlying raw buffer.
1395 ///
1396 /// For [layouts](crate::layout) others than [`RawLayout`](crate::layout::RawLayout), it is
1397 /// the same as [`from_buffer`](Self::from_buffer).
1398 ///
1399 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer).
1400 ///
1401 /// # Examples
1402 ///
1403 /// ```rust
1404 /// # #[cfg(not(feature = "portable-atomic-util"))]
1405 /// use std::sync::Arc;
1406 ///
1407 /// # #[cfg(feature = "portable-atomic-util")]
1408 /// # use portable_atomic_util::Arc;
1409 /// use arc_slice::{layout::RawLayout, ArcSlice};
1410 ///
1411 /// let s = ArcSlice::<[u8], RawLayout>::from_raw_buffer(Arc::new(vec![0, 1, 2]));
1412 /// assert_eq!(s, [0, 1, 2]);
1413 /// assert_eq!(
1414 /// s.try_into_buffer::<Arc<Vec<u8>>>().unwrap(),
1415 /// Arc::new(vec![0, 1, 2])
1416 /// );
1417 /// ```
1418 #[cfg(all(feature = "raw-buffer", feature = "oom-handling"))]
1419 pub fn from_raw_buffer<B: RawBuffer<S>>(buffer: B) -> Self {
1420 Self::from_raw_buffer_impl::<_, Infallible>(BufferWithMetadata::new(buffer, ()))
1421 .unwrap_infallible()
1422 }
1423
1424 /// Tries creating a new `ArcSlice` with the given underlying raw buffer, returning it if an
1425 /// allocation fails.
1426 ///
1427 /// For [layouts](crate::layout) others than [`RawLayout`](crate::layout::RawLayout), it is
1428 /// the same as [`try_from_buffer`](Self::try_from_buffer).
1429 ///
1430 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer).
1431 ///
1432 /// # Examples
1433 ///
1434 /// ```rust
1435 /// # #[cfg(not(feature = "portable-atomic-util"))]
1436 /// use std::sync::Arc;
1437 ///
1438 /// # #[cfg(feature = "portable-atomic-util")]
1439 /// # use portable_atomic_util::Arc;
1440 /// use arc_slice::{layout::RawLayout, ArcSlice};
1441 ///
1442 /// let s = ArcSlice::<[u8], RawLayout>::try_from_raw_buffer(Arc::new(vec![0, 1, 2])).unwrap();
1443 /// assert_eq!(s, [0, 1, 2]);
1444 /// assert_eq!(
1445 /// s.try_into_buffer::<Arc<Vec<u8>>>().unwrap(),
1446 /// Arc::new(vec![0, 1, 2])
1447 /// );
1448 /// ```
1449 #[cfg(feature = "raw-buffer")]
1450 pub fn try_from_raw_buffer<B: RawBuffer<S>>(buffer: B) -> Result<Self, B> {
1451 Self::from_raw_buffer_impl::<_, AllocError>(BufferWithMetadata::new(buffer, ()))
1452 .map_err(|(_, b)| b.buffer())
1453 }
1454
1455 /// Creates a new `ArcSlice` with the given underlying raw buffer with borrowed metadata.
1456 ///
1457 /// For [layouts](crate::layout) others than [`RawLayout`](crate::layout::RawLayout), it is
1458 /// the same as [`from_buffer`](Self::from_buffer).
1459 ///
1460 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1461 /// metadata can be retrieved with [`metadata`](Self::metadata).
1462 ///
1463 /// # Examples
1464 ///
1465 /// ```rust
1466 /// # #[cfg(not(feature = "portable-atomic-util"))]
1467 /// use std::sync::Arc;
1468 ///
1469 /// # #[cfg(feature = "portable-atomic-util")]
1470 /// # use portable_atomic_util::Arc;
1471 /// ///
1472 /// use arc_slice::buffer::{BorrowMetadata, Buffer};
1473 /// use arc_slice::{layout::RawLayout, ArcSlice};
1474 ///
1475 /// #[derive(Debug, PartialEq, Eq)]
1476 /// struct MyBuffer(Vec<u8>);
1477 /// impl Buffer<[u8]> for MyBuffer {
1478 /// fn as_slice(&self) -> &[u8] {
1479 /// &self.0
1480 /// }
1481 /// }
1482 /// #[derive(Debug, PartialEq, Eq)]
1483 /// struct MyMetadata;
1484 /// impl BorrowMetadata for MyBuffer {
1485 /// type Metadata = MyMetadata;
1486 /// fn borrow_metadata(&self) -> &Self::Metadata {
1487 /// &MyMetadata
1488 /// }
1489 /// }
1490 ///
1491 /// let buffer = Arc::new(MyBuffer(vec![0, 1, 2]));
1492 /// let s = ArcSlice::<[u8], RawLayout>::from_raw_buffer_with_borrowed_metadata(buffer);
1493 /// assert_eq!(s, [0, 1, 2]);
1494 /// assert_eq!(s.metadata::<MyMetadata>().unwrap(), &MyMetadata);
1495 /// assert_eq!(
1496 /// s.try_into_buffer::<Arc<MyBuffer>>().unwrap(),
1497 /// Arc::new(MyBuffer(vec![0, 1, 2]))
1498 /// );
1499 /// ```
1500 #[cfg(all(feature = "raw-buffer", feature = "oom-handling"))]
1501 pub fn from_raw_buffer_with_borrowed_metadata<B: RawBuffer<S> + BorrowMetadata>(
1502 buffer: B,
1503 ) -> Self {
1504 Self::from_dyn_buffer_impl::<_, Infallible>(buffer).unwrap_infallible()
1505 }
1506
1507 /// Tries creating a new `ArcSlice` with the given underlying raw buffer with borrowed metadata,
1508 /// returning it if an allocation fails.
1509 ///
1510 /// For [layouts](crate::layout) others than [`RawLayout`](crate::layout::RawLayout), it is
1511 /// the same as [`from_buffer`](Self::from_buffer).
1512 ///
1513 /// The buffer can be extracted back using [`try_into_buffer`](Self::try_into_buffer);
1514 /// metadata can be retrieved with [`metadata`](Self::metadata).
1515 ///
1516 /// Having an Arc allocation depends on the [layout](crate::layout) and the buffer type,
1517 /// e.g. there will be no allocation for a `Vec` with [`VecLayout`](crate::layout::VecLayout).
1518 ///
1519 /// # Examples
1520 ///
1521 /// ```rust
1522 /// # #[cfg(not(feature = "portable-atomic-util"))]
1523 /// use std::sync::Arc;
1524 ///
1525 /// # #[cfg(feature = "portable-atomic-util")]
1526 /// # use portable_atomic_util::Arc;
1527 /// ///
1528 /// use arc_slice::buffer::{BorrowMetadata, Buffer};
1529 /// use arc_slice::{layout::RawLayout, ArcSlice};
1530 ///
1531 /// #[derive(Debug, PartialEq, Eq)]
1532 /// struct MyBuffer(Vec<u8>);
1533 /// impl Buffer<[u8]> for MyBuffer {
1534 /// fn as_slice(&self) -> &[u8] {
1535 /// &self.0
1536 /// }
1537 /// }
1538 /// #[derive(Debug, PartialEq, Eq)]
1539 /// struct MyMetadata;
1540 /// impl BorrowMetadata for MyBuffer {
1541 /// type Metadata = MyMetadata;
1542 /// fn borrow_metadata(&self) -> &Self::Metadata {
1543 /// &MyMetadata
1544 /// }
1545 /// }
1546 ///
1547 /// let buffer = Arc::new(MyBuffer(vec![0, 1, 2]));
1548 /// let s =
1549 /// ArcSlice::<[u8], RawLayout>::try_from_raw_buffer_with_borrowed_metadata(buffer).unwrap();
1550 /// assert_eq!(s, [0, 1, 2]);
1551 /// assert_eq!(s.metadata::<MyMetadata>().unwrap(), &MyMetadata);
1552 /// assert_eq!(
1553 /// s.try_into_buffer::<Arc<MyBuffer>>().unwrap(),
1554 /// Arc::new(MyBuffer(vec![0, 1, 2]))
1555 /// );
1556 /// ```
1557 #[cfg(feature = "raw-buffer")]
1558 pub fn try_from_raw_buffer_with_borrowed_metadata<B: RawBuffer<S> + BorrowMetadata>(
1559 buffer: B,
1560 ) -> Result<Self, B> {
1561 Self::from_dyn_buffer_impl::<_, AllocError>(buffer).map_err(|(_, buffer)| buffer)
1562 }
1563}
1564
1565impl<L: StaticLayout> ArcSlice<[u8], L> {
1566 /// Creates a new `ArcSlice` from a static slice.
1567 ///
1568 /// The operation never allocates.
1569 ///
1570 /// # Examples
1571 ///
1572 /// ```rust
1573 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1574 ///
1575 /// static HELLO_WORLD: ArcSlice<[u8], ArcLayout<true, true>> =
1576 /// ArcSlice::<[u8], ArcLayout<true, true>>::from_static(b"hello world");
1577 /// ```
1578 pub const fn from_static(slice: &'static [u8]) -> Self {
1579 // MSRV 1.65 const `<*const _>::cast_mut` + 1.85 const `NonNull::new`
1580 let start = unsafe { NonNull::new_unchecked(slice.as_ptr() as _) };
1581 let length = slice.len();
1582 let data = unsafe { L::STATIC_DATA_UNCHECKED.assume_init() };
1583 Self::init(start, length, data)
1584 }
1585}
1586
1587impl<L: StaticLayout> ArcSlice<str, L> {
1588 /// Creates a new `ArcSlice` from a static str.
1589 ///
1590 /// The operation never allocates.
1591 ///
1592 /// # Examples
1593 ///
1594 /// ```rust
1595 /// use arc_slice::{layout::ArcLayout, ArcSlice};
1596 ///
1597 /// static HELLO_WORLD: ArcSlice<str, ArcLayout<true, true>> =
1598 /// ArcSlice::<str, ArcLayout<true, true>>::from_static("hello world");
1599 /// ```
1600 pub const fn from_static(slice: &'static str) -> Self {
1601 // MSRV 1.65 const `<*const _>::cast_mut` + 1.85 const `NonNull::new`
1602 let start = unsafe { NonNull::new_unchecked(slice.as_ptr() as _) };
1603 let length = slice.len();
1604 let data = unsafe { L::STATIC_DATA_UNCHECKED.assume_init() };
1605 Self::init(start, length, data)
1606 }
1607}
1608
1609impl<S: Slice + ?Sized, L: Layout> Drop for ArcSlice<S, L> {
1610 fn drop(&mut self) {
1611 unsafe { L::drop::<S, false>(self.start, self.length, &mut self.data) };
1612 }
1613}
1614
1615impl<
1616 S: Slice + ?Sized,
1617 #[cfg(feature = "oom-handling")] L: Layout,
1618 #[cfg(not(feature = "oom-handling"))] L: CloneNoAllocLayout,
1619 > Clone for ArcSlice<S, L>
1620{
1621 fn clone(&self) -> Self {
1622 self.clone_impl::<Infallible>().unwrap_infallible()
1623 }
1624}
1625
1626impl<S: Slice + ?Sized, L: Layout> Deref for ArcSlice<S, L> {
1627 type Target = S;
1628
1629 fn deref(&self) -> &Self::Target {
1630 self.as_slice()
1631 }
1632}
1633
1634impl<S: Slice + ?Sized, L: Layout> AsRef<S> for ArcSlice<S, L> {
1635 fn as_ref(&self) -> &S {
1636 self
1637 }
1638}
1639
1640impl<S: Hash + Slice + ?Sized, L: Layout> Hash for ArcSlice<S, L> {
1641 fn hash<H>(&self, state: &mut H)
1642 where
1643 H: Hasher,
1644 {
1645 self.as_slice().hash(state);
1646 }
1647}
1648
1649impl<S: Slice + ?Sized, L: Layout> Borrow<S> for ArcSlice<S, L> {
1650 fn borrow(&self) -> &S {
1651 self
1652 }
1653}
1654
1655impl<S: Emptyable + ?Sized, L: StaticLayout> Default for ArcSlice<S, L> {
1656 fn default() -> Self {
1657 Self::new_empty(NonNull::dangling(), 0).unwrap_checked()
1658 }
1659}
1660
1661impl<S: fmt::Debug + Slice + ?Sized, L: Layout> fmt::Debug for ArcSlice<S, L> {
1662 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1663 debug_slice(self.as_slice(), f)
1664 }
1665}
1666
1667impl<S: fmt::Display + Slice + ?Sized, L: Layout> fmt::Display for ArcSlice<S, L> {
1668 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1669 self.as_slice().fmt(f)
1670 }
1671}
1672
1673impl<S: Slice<Item = u8> + ?Sized, L: Layout> fmt::LowerHex for ArcSlice<S, L> {
1674 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1675 lower_hex(self.to_slice(), f)
1676 }
1677}
1678
1679impl<S: Slice<Item = u8> + ?Sized, L: Layout> fmt::UpperHex for ArcSlice<S, L> {
1680 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1681 upper_hex(self.to_slice(), f)
1682 }
1683}
1684
1685impl<S: PartialEq + Slice + ?Sized, L: Layout> PartialEq for ArcSlice<S, L> {
1686 fn eq(&self, other: &ArcSlice<S, L>) -> bool {
1687 self.as_slice() == other.as_slice()
1688 }
1689}
1690
1691impl<S: PartialEq + Slice + ?Sized, L: Layout> Eq for ArcSlice<S, L> {}
1692
1693impl<S: PartialOrd + Slice + ?Sized, L: Layout> PartialOrd for ArcSlice<S, L> {
1694 fn partial_cmp(&self, other: &ArcSlice<S, L>) -> Option<cmp::Ordering> {
1695 self.as_slice().partial_cmp(other.as_slice())
1696 }
1697}
1698
1699impl<S: Ord + Slice + ?Sized, L: Layout> Ord for ArcSlice<S, L> {
1700 fn cmp(&self, other: &ArcSlice<S, L>) -> cmp::Ordering {
1701 self.as_slice().cmp(other.as_slice())
1702 }
1703}
1704
1705impl<S: PartialEq + Slice + ?Sized, L: Layout> PartialEq<S> for ArcSlice<S, L> {
1706 fn eq(&self, other: &S) -> bool {
1707 self.as_slice() == other
1708 }
1709}
1710
1711impl<'a, S: PartialEq + Slice + ?Sized, L: Layout> PartialEq<&'a S> for ArcSlice<S, L> {
1712 fn eq(&self, other: &&'a S) -> bool {
1713 self.as_slice() == *other
1714 }
1715}
1716
1717impl<T: PartialEq + Send + Sync + 'static, L: Layout, const N: usize> PartialEq<[T; N]>
1718 for ArcSlice<[T], L>
1719{
1720 fn eq(&self, other: &[T; N]) -> bool {
1721 *other == **self
1722 }
1723}
1724
1725impl<'a, T: PartialEq + Send + Sync + 'static, L: Layout, const N: usize> PartialEq<&'a [T; N]>
1726 for ArcSlice<[T], L>
1727{
1728 fn eq(&self, other: &&'a [T; N]) -> bool {
1729 **other == **self
1730 }
1731}
1732
1733impl<T: PartialEq + Send + Sync + 'static, L: Layout, const N: usize> PartialEq<ArcSlice<[T], L>>
1734 for [T; N]
1735{
1736 fn eq(&self, other: &ArcSlice<[T], L>) -> bool {
1737 **other == *self
1738 }
1739}
1740
1741impl<T: PartialEq + Send + Sync + 'static, L: Layout> PartialEq<ArcSlice<[T], L>> for [T] {
1742 fn eq(&self, other: &ArcSlice<[T], L>) -> bool {
1743 **other == *self
1744 }
1745}
1746
1747impl<L: Layout> PartialEq<ArcSlice<str, L>> for str {
1748 fn eq(&self, other: &ArcSlice<str, L>) -> bool {
1749 **other == *self
1750 }
1751}
1752
1753impl<T: PartialEq + Send + Sync + 'static, L: Layout> PartialEq<Vec<T>> for ArcSlice<[T], L> {
1754 fn eq(&self, other: &Vec<T>) -> bool {
1755 **self == **other
1756 }
1757}
1758
1759impl<L: Layout> PartialEq<String> for ArcSlice<str, L> {
1760 fn eq(&self, other: &String) -> bool {
1761 **self == **other
1762 }
1763}
1764
1765impl<T: PartialEq + Send + Sync + 'static, L: Layout> PartialEq<ArcSlice<[T], L>> for Vec<T> {
1766 fn eq(&self, other: &ArcSlice<[T], L>) -> bool {
1767 **self == **other
1768 }
1769}
1770
1771impl<L: Layout> PartialEq<ArcSlice<str, L>> for String {
1772 fn eq(&self, other: &ArcSlice<str, L>) -> bool {
1773 **self == **other
1774 }
1775}
1776
1777#[cfg(feature = "oom-handling")]
1778impl<S: Slice + ?Sized, L: Layout> From<&S> for ArcSlice<S, L>
1779where
1780 S::Item: Copy,
1781{
1782 fn from(value: &S) -> Self {
1783 Self::from_slice(value)
1784 }
1785}
1786
1787#[cfg(feature = "oom-handling")]
1788impl<T: Copy + Send + Sync + 'static, L: Layout, const N: usize> From<&[T; N]>
1789 for ArcSlice<[T], L>
1790{
1791 fn from(value: &[T; N]) -> Self {
1792 Self::from_slice(value)
1793 }
1794}
1795
1796#[cfg(feature = "oom-handling")]
1797impl<T: Send + Sync + 'static, L: Layout, const N: usize> From<[T; N]> for ArcSlice<[T], L> {
1798 fn from(value: [T; N]) -> Self {
1799 Self::from_array(value)
1800 }
1801}
1802
1803#[cfg(not(feature = "oom-handling"))]
1804impl<S: Slice + ?Sized> From<Box<S>> for ArcSlice<S, BoxedSliceLayout> {
1805 fn from(value: Box<S>) -> Self {
1806 Self::from_vec(unsafe { S::from_vec_unchecked(value.into_boxed_slice().into_vec()) })
1807 }
1808}
1809#[cfg(not(feature = "oom-handling"))]
1810impl<S: Slice + ?Sized> From<Box<S>> for ArcSlice<S, VecLayout> {
1811 fn from(value: Box<S>) -> Self {
1812 Self::from_vec(unsafe { S::from_vec_unchecked(value.into_boxed_slice().into_vec()) })
1813 }
1814}
1815#[cfg(feature = "oom-handling")]
1816impl<S: Slice + ?Sized, L: AnyBufferLayout> From<Box<S>> for ArcSlice<S, L> {
1817 fn from(value: Box<S>) -> Self {
1818 Self::from_vec(unsafe { S::from_vec_unchecked(value.into_boxed_slice().into_vec()) })
1819 }
1820}
1821
1822#[cfg(not(feature = "oom-handling"))]
1823impl<T: Send + Sync + 'static> From<Vec<T>> for ArcSlice<[T], VecLayout> {
1824 fn from(value: Vec<T>) -> Self {
1825 Self::from_vec(value)
1826 }
1827}
1828#[cfg(feature = "oom-handling")]
1829impl<T: Send + Sync + 'static, L: AnyBufferLayout> From<Vec<T>> for ArcSlice<[T], L> {
1830 fn from(value: Vec<T>) -> Self {
1831 Self::from_vec(value)
1832 }
1833}
1834
1835#[cfg(not(feature = "oom-handling"))]
1836impl From<String> for ArcSlice<str, crate::layout::VecLayout> {
1837 fn from(value: String) -> Self {
1838 Self::from_vec(value)
1839 }
1840}
1841#[cfg(feature = "oom-handling")]
1842impl<L: AnyBufferLayout> From<String> for ArcSlice<str, L> {
1843 fn from(value: String) -> Self {
1844 Self::from_vec(value)
1845 }
1846}
1847
1848impl<T: Send + Sync + 'static, L: Layout, const N: usize> TryFrom<ArcSlice<[T], L>> for [T; N] {
1849 type Error = ArcSlice<[T], L>;
1850 fn try_from(value: ArcSlice<[T], L>) -> Result<Self, Self::Error> {
1851 let mut this = ManuallyDrop::new(value);
1852 unsafe { L::take_array::<T, N>(this.start, this.length, &mut this.data) }
1853 .ok_or_else(|| ManuallyDrop::into_inner(this))
1854 }
1855}
1856
1857#[cfg(feature = "oom-handling")]
1858impl<L: Layout> core::str::FromStr for ArcSlice<str, L> {
1859 type Err = Infallible;
1860
1861 fn from_str(s: &str) -> Result<Self, Self::Err> {
1862 Ok(s.into())
1863 }
1864}
1865
1866#[cfg(feature = "std")]
1867const _: () = {
1868 extern crate std;
1869
1870 impl<L: Layout> std::io::Read for ArcSlice<[u8], L> {
1871 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
1872 let n = cmp::min(self.len(), buf.len());
1873 buf[..n].copy_from_slice(&self[..n]);
1874 Ok(n)
1875 }
1876 }
1877};
1878
1879/// A borrowed view of an [`ArcSlice`].
1880///
1881/// `ArcSliceBorrow` is roughly equivalent to `(&S, &ArcSlice<S, L>)`. A new `ArcSlice` instance
1882/// can be obtained with [`clone_arc`].
1883/// <br>
1884/// One advantage of using `ArcSliceBorrow` is that [`clone_arc`] doesn't need to perform bound
1885/// checks that was done at `ArcSliceBorrow` creation; using `(&S, &ArcSlice<S, L>)` however
1886/// would require to check bounds a second time when using [`ArcSlice::subslice_from_ref`].
1887///
1888/// When using [`ArcLayout`], `ArcSliceBorrow` is even more efficient, because it can directly
1889/// embed the internal Arc instead of an `ArcSlice` reference, saving one indirection.
1890///
1891/// # Examples
1892///
1893/// ```rust
1894/// use arc_slice::ArcSlice;
1895///
1896/// let s = ArcSlice::<[u8]>::from(b"hello world");
1897/// let borrow = s.borrow(..5);
1898/// assert_eq!(&borrow[..], b"hello");
1899/// let s2: ArcSlice<[u8]> = borrow.clone_arc();
1900/// ```
1901///
1902/// [`clone_arc`]: Self::clone_arc
1903/// [`ArcLayout`]: crate::layout::ArcLayout
1904pub struct ArcSliceBorrow<'a, S: Slice + ?Sized, L: Layout = DefaultLayout> {
1905 start: NonNull<S::Item>,
1906 length: usize,
1907 ptr: *const (),
1908 _phantom: PhantomData<&'a ArcSlice<S, L>>,
1909}
1910
1911unsafe impl<S: Slice + ?Sized, L: Layout> Send for ArcSliceBorrow<'_, S, L> {}
1912unsafe impl<S: Slice + ?Sized, L: Layout> Sync for ArcSliceBorrow<'_, S, L> {}
1913
1914impl<S: Slice + ?Sized, L: Layout> Clone for ArcSliceBorrow<'_, S, L> {
1915 fn clone(&self) -> Self {
1916 *self
1917 }
1918}
1919
1920impl<S: Slice + ?Sized, L: Layout> Copy for ArcSliceBorrow<'_, S, L> {}
1921
1922impl<S: Slice + ?Sized, L: Layout> Deref for ArcSliceBorrow<'_, S, L> {
1923 type Target = S;
1924
1925 fn deref(&self) -> &Self::Target {
1926 self.as_slice()
1927 }
1928}
1929
1930impl<S: fmt::Debug + Slice + ?Sized, L: Layout> fmt::Debug for ArcSliceBorrow<'_, S, L> {
1931 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1932 debug_slice(&**self, f)
1933 }
1934}
1935
1936impl<'a, S: Slice + ?Sized, L: Layout> ArcSliceBorrow<'a, S, L> {
1937 fn clone_arc_impl<E: AllocErrorImpl>(self) -> Result<ArcSlice<S, L>, E> {
1938 if let Some(empty) = ArcSlice::new_empty(self.start, self.length) {
1939 return Ok(empty);
1940 }
1941 let clone = || {
1942 let arc_slice = unsafe { &*self.ptr.cast::<ArcSlice<S, L>>() };
1943 L::clone::<S, E>(arc_slice.start, arc_slice.length, &arc_slice.data)
1944 };
1945 let data = L::clone_borrowed_data::<S>(self.ptr).map_or_else(clone, Ok)?;
1946 Ok(ArcSlice {
1947 start: self.start,
1948 length: self.length,
1949 data: ManuallyDrop::new(data),
1950 })
1951 }
1952
1953 /// Tries cloning the `ArcSliceBorrow` into a subslice of the borrowed [`ArcSlice`], returning
1954 /// an error if an allocation fails.
1955 ///
1956 /// The returned [`ArcSlice`] has the same slice as the original borrow.
1957 ///
1958 /// The operation may not allocate, see
1959 /// [`CloneNoAllocLayout`](crate::layout::CloneNoAllocLayout) documentation.
1960 ///
1961 /// # Examples
1962 ///
1963 /// ```rust
1964 /// use arc_slice::ArcSlice;
1965 ///
1966 /// let s = ArcSlice::<[u8]>::from(b"hello world");
1967 /// let borrow = s.borrow(..5);
1968 /// assert_eq!(&borrow[..], b"hello");
1969 /// let s2: ArcSlice<[u8]> = borrow.try_clone_arc().unwrap();
1970 /// assert_eq!(s2, b"hello");
1971 /// ```
1972 pub fn try_clone_arc(self) -> Result<ArcSlice<S, L>, AllocError> {
1973 self.clone_arc_impl::<AllocError>()
1974 }
1975
1976 /// Returns the borrowed slice.
1977 ///
1978 /// Roughly equivalent to `&self[..]`, but using the borrow lifetime instead of self's one.
1979 ///
1980 /// # Examples
1981 ///
1982 /// ```rust
1983 /// use arc_slice::ArcSlice;
1984 ///
1985 /// let s = ArcSlice::<[u8]>::from(b"hello world");
1986 /// assert_eq!(s.as_slice(), b"hello world");
1987 /// ```
1988 pub fn as_slice(&self) -> &'a S {
1989 unsafe { S::from_raw_parts(self.start, self.length) }
1990 }
1991
1992 /// Reborrows a subslice of an `ArcSliceBorrow` with a given range.
1993 ///
1994 /// The range is applied to the `ArcSliceBorrow` slice, not to the underlying `ArcSlice` one.
1995 ///
1996 /// # Examples
1997 ///
1998 /// ```rust
1999 /// use arc_slice::ArcSlice;
2000 ///
2001 /// let s = ArcSlice::<[u8]>::from(b"hello world");
2002 /// let borrow = s.borrow(..5);
2003 /// assert_eq!(&borrow[..], b"hello");
2004 /// let reborrow = borrow.reborrow(2..4);
2005 /// assert_eq!(&reborrow[..], b"ll");
2006 /// ```
2007 pub fn reborrow(&self, range: impl RangeBounds<usize>) -> ArcSliceBorrow<'a, S, L>
2008 where
2009 S: Subsliceable,
2010 {
2011 unsafe { self.reborrow_impl(range_offset_len(self.as_slice(), range)) }
2012 }
2013
2014 /// Reborrows a subslice of an `ArcSliceBorrow` from a slice reference.
2015 ///
2016 /// The slice reference must be contained into the `ArcSliceBorrow` slice, not into the underlying `ArcSlice` one.
2017 ///
2018 /// # Examples
2019 ///
2020 /// ```rust
2021 /// use arc_slice::ArcSlice;
2022 ///
2023 /// let s = ArcSlice::<[u8]>::from(b"hello world");
2024 /// let hello = &s[..5];
2025 /// let borrow = s.borrow_from_ref(hello);
2026 /// assert_eq!(&borrow[..], b"hello");
2027 /// let ll = &borrow[2..4];
2028 /// let reborrow = borrow.reborrow_from_ref(ll);
2029 /// assert_eq!(&reborrow[..], b"ll");
2030 /// ```
2031 pub fn reborrow_from_ref(&self, subset: &S) -> ArcSliceBorrow<'a, S, L>
2032 where
2033 S: Subsliceable,
2034 {
2035 unsafe { self.reborrow_impl(subslice_offset_len(self.as_slice(), subset)) }
2036 }
2037
2038 unsafe fn reborrow_impl(&self, (offset, len): (usize, usize)) -> ArcSliceBorrow<'a, S, L>
2039 where
2040 S: Subsliceable,
2041 {
2042 ArcSliceBorrow {
2043 start: unsafe { self.start.add(offset) },
2044 length: len,
2045 ptr: self.ptr,
2046 _phantom: PhantomData,
2047 }
2048 }
2049}
2050
2051impl<
2052 S: Slice + ?Sized,
2053 #[cfg(feature = "oom-handling")] L: Layout,
2054 #[cfg(not(feature = "oom-handling"))] L: CloneNoAllocLayout,
2055 > ArcSliceBorrow<'_, S, L>
2056{
2057 /// Clone the `ArcSliceBorrow` into a subslice of the borrowed [`ArcSlice`].
2058 ///
2059 /// The returned [`ArcSlice`] has the same slice as the original borrow.
2060 ///
2061 ///
2062 /// # Examples
2063 ///
2064 /// ```rust
2065 /// use arc_slice::ArcSlice;
2066 ///
2067 /// let s = ArcSlice::<[u8]>::from(b"hello world");
2068 /// let borrow = s.borrow(..5);
2069 /// assert_eq!(&borrow[..], b"hello");
2070 /// let s2: ArcSlice<[u8]> = borrow.clone_arc();
2071 /// assert_eq!(s2, b"hello");
2072 /// ```
2073 pub fn clone_arc(self) -> ArcSlice<S, L> {
2074 self.clone_arc_impl::<Infallible>().unwrap_infallible()
2075 }
2076}