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}