1#[allow(unused_imports)]
12use rawpointer::PointerExt;
13
14#[cfg(target_has_atomic = "ptr")]
15use alloc::sync::Arc;
16
17#[cfg(not(target_has_atomic = "ptr"))]
18use portable_atomic_util::Arc;
19
20#[cfg(not(feature = "std"))]
21use alloc::vec::Vec;
22use std::mem::MaybeUninit;
23use std::mem::{self, size_of};
24use std::ptr::NonNull;
25
26use crate::{ArcArray, Array, ArrayBase, ArrayRef, CowRepr, Dimension, OwnedArcRepr, OwnedRepr, RawViewRepr, ViewRepr};
27
28#[allow(clippy::missing_safety_doc)] pub unsafe trait RawData: Sized
39{
40 type Elem;
42
43 #[doc(hidden)]
44 fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool;
45
46 private_decl! {}
47}
48
49#[allow(clippy::missing_safety_doc)] pub unsafe trait RawDataMut: RawData
56{
57 #[doc(hidden)]
65 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
66 where
67 Self: Sized,
68 D: Dimension;
69
70 #[doc(hidden)]
75 fn try_is_unique(&mut self) -> Option<bool>;
76}
77
78#[allow(clippy::missing_safety_doc)] pub unsafe trait RawDataClone: RawData
85{
86 #[doc(hidden)]
87 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>);
89
90 #[doc(hidden)]
91 unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
92 {
93 let (data, ptr) = other.clone_with_ptr(ptr);
94 *self = data;
95 ptr
96 }
97}
98
99#[allow(clippy::missing_safety_doc)] pub unsafe trait Data: RawData
106{
107 #[doc(hidden)]
109 #[allow(clippy::wrong_self_convention)]
110 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
111 where
112 Self::Elem: Clone,
113 D: Dimension;
114
115 #[doc(hidden)]
118 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
119 where D: Dimension;
120
121 #[doc(hidden)]
124 #[allow(clippy::wrong_self_convention)]
125 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
126 where
127 Self::Elem: Clone,
128 D: Dimension,
129 {
130 self_.to_owned().into_shared()
132 }
133}
134
135#[allow(clippy::missing_safety_doc)] pub unsafe trait DataMut: Data + RawDataMut
149{
150 #[doc(hidden)]
152 #[inline]
153 fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
154 where
155 Self: Sized,
156 D: Dimension,
157 {
158 Self::try_ensure_unique(self_)
159 }
160
161 #[doc(hidden)]
163 #[inline]
164 #[allow(clippy::wrong_self_convention)] fn is_unique(&mut self) -> bool
166 {
167 self.try_is_unique().unwrap()
168 }
169}
170
171unsafe impl<A> RawData for RawViewRepr<*const A>
172{
173 type Elem = A;
174
175 #[inline(always)]
176 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
177 {
178 true
179 }
180
181 private_impl! {}
182}
183
184unsafe impl<A> RawDataClone for RawViewRepr<*const A>
185{
186 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
187 {
188 (*self, ptr)
189 }
190}
191
192unsafe impl<A> RawData for RawViewRepr<*mut A>
193{
194 type Elem = A;
195
196 #[inline(always)]
197 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
198 {
199 true
200 }
201
202 private_impl! {}
203}
204
205unsafe impl<A> RawDataMut for RawViewRepr<*mut A>
206{
207 #[inline]
208 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
209 where
210 Self: Sized,
211 D: Dimension,
212 {
213 }
214
215 #[inline]
216 fn try_is_unique(&mut self) -> Option<bool>
217 {
218 None
219 }
220}
221
222unsafe impl<A> RawDataClone for RawViewRepr<*mut A>
223{
224 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
225 {
226 (*self, ptr)
227 }
228}
229
230unsafe impl<A> RawData for OwnedArcRepr<A>
231{
232 type Elem = A;
233
234 fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool
235 {
236 self.0._is_pointer_inbounds(self_ptr)
237 }
238
239 private_impl! {}
240}
241
242unsafe impl<A> RawDataMut for OwnedArcRepr<A>
244where A: Clone
245{
246 fn try_ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
247 where
248 Self: Sized,
249 D: Dimension,
250 {
251 if Arc::get_mut(&mut self_.data.0).is_some() {
252 return;
253 }
254 if self_.parts.dim.size() <= self_.data.0.len() / 2 {
255 *self_ = self_.to_owned().into_shared();
258 return;
259 }
260 let rcvec = &mut self_.data.0;
261 let a_size = mem::size_of::<A>() as isize;
262 let our_off = if a_size != 0 {
263 (self_.parts.ptr.as_ptr() as isize - rcvec.as_ptr() as isize) / a_size
264 } else {
265 0
266 };
267 let rvec = Arc::make_mut(rcvec);
268 unsafe {
269 self_.parts.ptr = rvec.as_nonnull_mut().offset(our_off);
270 }
271 }
272
273 fn try_is_unique(&mut self) -> Option<bool>
274 {
275 Some(Arc::get_mut(&mut self.0).is_some())
276 }
277}
278
279unsafe impl<A> Data for OwnedArcRepr<A>
280{
281 fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
282 where
283 A: Clone,
284 D: Dimension,
285 {
286 Self::ensure_unique(&mut self_);
287 let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
288 unsafe {
290 ArrayBase::from_data_ptr(data, self_.parts.ptr).with_strides_dim(self_.parts.strides, self_.parts.dim)
291 }
292 }
293
294 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
295 where D: Dimension
296 {
297 match Arc::try_unwrap(self_.data.0) {
298 Ok(owned_data) => unsafe {
299 Ok(ArrayBase::from_data_ptr(owned_data, self_.parts.ptr)
301 .with_strides_dim(self_.parts.strides, self_.parts.dim))
302 },
303 Err(arc_data) => unsafe {
304 Err(ArrayBase::from_data_ptr(OwnedArcRepr(arc_data), self_.parts.ptr)
307 .with_strides_dim(self_.parts.strides, self_.parts.dim))
308 },
309 }
310 }
311
312 #[allow(clippy::wrong_self_convention)]
313 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
314 where
315 Self::Elem: Clone,
316 D: Dimension,
317 {
318 self_.clone()
320 }
321}
322
323unsafe impl<A> DataMut for OwnedArcRepr<A> where A: Clone {}
324
325unsafe impl<A> RawDataClone for OwnedArcRepr<A>
326{
327 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
328 {
329 (self.clone(), ptr)
331 }
332}
333
334unsafe impl<A> RawData for OwnedRepr<A>
335{
336 type Elem = A;
337
338 fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool
339 {
340 let slc = self.as_slice();
341 let ptr = slc.as_ptr() as *mut A;
342 let end = unsafe { ptr.add(slc.len()) };
343 self_ptr >= ptr && self_ptr <= end
344 }
345
346 private_impl! {}
347}
348
349unsafe impl<A> RawDataMut for OwnedRepr<A>
350{
351 #[inline]
352 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
353 where
354 Self: Sized,
355 D: Dimension,
356 {
357 }
358
359 #[inline]
360 fn try_is_unique(&mut self) -> Option<bool>
361 {
362 Some(true)
363 }
364}
365
366unsafe impl<A> Data for OwnedRepr<A>
367{
368 #[inline]
369 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
370 where
371 A: Clone,
372 D: Dimension,
373 {
374 self_
375 }
376
377 #[inline]
378 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
379 where D: Dimension
380 {
381 Ok(self_)
382 }
383}
384
385unsafe impl<A> DataMut for OwnedRepr<A> {}
386
387unsafe impl<A> RawDataClone for OwnedRepr<A>
388where A: Clone
389{
390 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
391 {
392 let mut u = self.clone();
393 let mut new_ptr = u.as_nonnull_mut();
394 if size_of::<A>() != 0 {
395 let our_off = (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
396 new_ptr = new_ptr.offset(our_off);
397 }
398 (u, new_ptr)
399 }
400
401 unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
402 {
403 let our_off = if size_of::<A>() != 0 {
404 (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
405 } else {
406 0
407 };
408 self.clone_from(other);
409 self.as_nonnull_mut().offset(our_off)
410 }
411}
412
413unsafe impl<A> RawData for ViewRepr<&A>
414{
415 type Elem = A;
416
417 #[inline(always)]
418 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
419 {
420 true
421 }
422
423 private_impl! {}
424}
425
426unsafe impl<A> Data for ViewRepr<&A>
427{
428 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
429 where
430 Self::Elem: Clone,
431 D: Dimension,
432 {
433 self_.to_owned()
434 }
435
436 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
437 where D: Dimension
438 {
439 Err(self_)
440 }
441}
442
443unsafe impl<A> RawDataClone for ViewRepr<&A>
444{
445 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
446 {
447 (*self, ptr)
448 }
449}
450
451unsafe impl<A> RawData for ViewRepr<&mut A>
452{
453 type Elem = A;
454
455 #[inline(always)]
456 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
457 {
458 true
459 }
460
461 private_impl! {}
462}
463
464unsafe impl<A> RawDataMut for ViewRepr<&mut A>
465{
466 #[inline]
467 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
468 where
469 Self: Sized,
470 D: Dimension,
471 {
472 }
473
474 #[inline]
475 fn try_is_unique(&mut self) -> Option<bool>
476 {
477 Some(true)
478 }
479}
480
481unsafe impl<A> Data for ViewRepr<&mut A>
482{
483 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
484 where
485 Self::Elem: Clone,
486 D: Dimension,
487 {
488 self_.to_owned()
489 }
490
491 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
492 where D: Dimension
493 {
494 Err(self_)
495 }
496}
497
498unsafe impl<A> DataMut for ViewRepr<&mut A> {}
499
500#[allow(clippy::missing_safety_doc)] pub unsafe trait DataOwned: Data
514{
515 type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>> + RawDataSubst<Self::Elem, Output = Self>;
517 #[doc(hidden)]
518 fn new(elements: Vec<Self::Elem>) -> Self;
519
520 #[doc(hidden)]
523 #[allow(clippy::wrong_self_convention)]
524 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
525 where
526 Self::Elem: Clone,
527 D: Dimension;
528}
529
530#[allow(clippy::missing_safety_doc)] pub unsafe trait DataShared: Clone + Data + RawDataClone {}
537
538unsafe impl<A> DataShared for OwnedArcRepr<A> {}
539unsafe impl<A> DataShared for ViewRepr<&A> {}
540
541unsafe impl<A> DataOwned for OwnedRepr<A>
542{
543 type MaybeUninit = OwnedRepr<MaybeUninit<A>>;
544
545 fn new(elements: Vec<A>) -> Self
546 {
547 OwnedRepr::from(elements)
548 }
549
550 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
551 where
552 A: Clone,
553 D: Dimension,
554 {
555 ArcArray::from(self_)
556 }
557}
558
559unsafe impl<A> DataOwned for OwnedArcRepr<A>
560{
561 type MaybeUninit = OwnedArcRepr<MaybeUninit<A>>;
562
563 fn new(elements: Vec<A>) -> Self
564 {
565 OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
566 }
567
568 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
569 where
570 A: Clone,
571 D: Dimension,
572 {
573 self_
574 }
575}
576
577unsafe impl<A> RawData for CowRepr<'_, A>
578{
579 type Elem = A;
580
581 #[inline]
582 fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool
583 {
584 match self {
585 CowRepr::View(view) => view._is_pointer_inbounds(ptr),
586 CowRepr::Owned(data) => data._is_pointer_inbounds(ptr),
587 }
588 }
589
590 private_impl! {}
591}
592
593unsafe impl<A> RawDataMut for CowRepr<'_, A>
594where A: Clone
595{
596 #[inline]
597 fn try_ensure_unique<D>(array: &mut ArrayBase<Self, D>)
598 where
599 Self: Sized,
600 D: Dimension,
601 {
602 match array.data {
603 CowRepr::View(_) => {
604 let owned = ArrayRef::to_owned(array);
605 array.data = CowRepr::Owned(owned.data);
606 array.parts.ptr = owned.parts.ptr;
607 array.parts.dim = owned.parts.dim;
608 array.parts.strides = owned.parts.strides;
609 }
610 CowRepr::Owned(_) => {}
611 }
612 }
613
614 #[inline]
615 fn try_is_unique(&mut self) -> Option<bool>
616 {
617 Some(self.is_owned())
618 }
619}
620
621unsafe impl<A> RawDataClone for CowRepr<'_, A>
622where A: Clone
623{
624 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
625 {
626 match self {
627 CowRepr::View(view) => {
628 let (new_view, ptr) = view.clone_with_ptr(ptr);
629 (CowRepr::View(new_view), ptr)
630 }
631 CowRepr::Owned(data) => {
632 let (new_data, ptr) = data.clone_with_ptr(ptr);
633 (CowRepr::Owned(new_data), ptr)
634 }
635 }
636 }
637
638 unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
639 {
640 match (&mut *self, other) {
641 (CowRepr::View(self_), CowRepr::View(other)) => self_.clone_from_with_ptr(other, ptr),
642 (CowRepr::Owned(self_), CowRepr::Owned(other)) => self_.clone_from_with_ptr(other, ptr),
643 (_, CowRepr::Owned(other)) => {
644 let (cloned, ptr) = other.clone_with_ptr(ptr);
645 *self = CowRepr::Owned(cloned);
646 ptr
647 }
648 (_, CowRepr::View(other)) => {
649 let (cloned, ptr) = other.clone_with_ptr(ptr);
650 *self = CowRepr::View(cloned);
651 ptr
652 }
653 }
654 }
655}
656
657unsafe impl<'a, A> Data for CowRepr<'a, A>
658{
659 #[inline]
660 fn into_owned<D>(self_: ArrayBase<CowRepr<'a, A>, D>) -> Array<Self::Elem, D>
661 where
662 A: Clone,
663 D: Dimension,
664 {
665 match self_.data {
666 CowRepr::View(_) => self_.to_owned(),
667 CowRepr::Owned(data) => unsafe {
668 ArrayBase::from_data_ptr(data, self_.parts.ptr).with_strides_dim(self_.parts.strides, self_.parts.dim)
670 },
671 }
672 }
673
674 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
675 where D: Dimension
676 {
677 match self_.data {
678 CowRepr::View(_) => Err(self_),
679 CowRepr::Owned(data) => unsafe {
680 Ok(ArrayBase::from_data_ptr(data, self_.parts.ptr)
682 .with_strides_dim(self_.parts.strides, self_.parts.dim))
683 },
684 }
685 }
686}
687
688unsafe impl<A> DataMut for CowRepr<'_, A> where A: Clone {}
689
690unsafe impl<'a, A> DataOwned for CowRepr<'a, A>
691{
692 type MaybeUninit = CowRepr<'a, MaybeUninit<A>>;
693
694 fn new(elements: Vec<A>) -> Self
695 {
696 CowRepr::Owned(OwnedRepr::new(elements))
697 }
698
699 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
700 where
701 A: Clone,
702 D: Dimension,
703 {
704 self_.into_owned().into_shared()
705 }
706}
707
708pub trait RawDataSubst<A>: RawData
715{
716 type Output: RawData<Elem = A>;
718
719 unsafe fn data_subst(self) -> Self::Output;
726}
727
728impl<A, B> RawDataSubst<B> for OwnedRepr<A>
729{
730 type Output = OwnedRepr<B>;
731
732 unsafe fn data_subst(self) -> Self::Output
733 {
734 self.data_subst()
735 }
736}
737
738impl<A, B> RawDataSubst<B> for OwnedArcRepr<A>
739{
740 type Output = OwnedArcRepr<B>;
741
742 unsafe fn data_subst(self) -> Self::Output
743 {
744 OwnedArcRepr(Arc::from_raw(Arc::into_raw(self.0) as *const OwnedRepr<B>))
745 }
746}
747
748impl<A, B> RawDataSubst<B> for RawViewRepr<*const A>
749{
750 type Output = RawViewRepr<*const B>;
751
752 unsafe fn data_subst(self) -> Self::Output
753 {
754 RawViewRepr::new()
755 }
756}
757
758impl<A, B> RawDataSubst<B> for RawViewRepr<*mut A>
759{
760 type Output = RawViewRepr<*mut B>;
761
762 unsafe fn data_subst(self) -> Self::Output
763 {
764 RawViewRepr::new()
765 }
766}
767
768impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a A>
769{
770 type Output = ViewRepr<&'a B>;
771
772 unsafe fn data_subst(self) -> Self::Output
773 {
774 ViewRepr::new()
775 }
776}
777
778impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a mut A>
779{
780 type Output = ViewRepr<&'a mut B>;
781
782 unsafe fn data_subst(self) -> Self::Output
783 {
784 ViewRepr::new()
785 }
786}
787
788impl<'a, A: 'a, B: 'a> RawDataSubst<B> for CowRepr<'a, A>
789{
790 type Output = CowRepr<'a, B>;
791
792 unsafe fn data_subst(self) -> Self::Output
793 {
794 match self {
795 CowRepr::View(view) => CowRepr::View(view.data_subst()),
796 CowRepr::Owned(owned) => CowRepr::Owned(owned.data_subst()),
797 }
798 }
799}