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