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, 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_.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_.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_.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 { ArrayBase::from_data_ptr(data, self_.ptr).with_strides_dim(self_.strides, self_.dim) }
290 }
291
292 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
293 where D: Dimension
294 {
295 match Arc::try_unwrap(self_.data.0) {
296 Ok(owned_data) => unsafe {
297 Ok(ArrayBase::from_data_ptr(owned_data, self_.ptr).with_strides_dim(self_.strides, self_.dim))
299 },
300 Err(arc_data) => unsafe {
301 Err(ArrayBase::from_data_ptr(OwnedArcRepr(arc_data), self_.ptr)
304 .with_strides_dim(self_.strides, self_.dim))
305 },
306 }
307 }
308
309 #[allow(clippy::wrong_self_convention)]
310 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
311 where
312 Self::Elem: Clone,
313 D: Dimension,
314 {
315 self_.clone()
317 }
318}
319
320unsafe impl<A> DataMut for OwnedArcRepr<A> where A: Clone {}
321
322unsafe impl<A> RawDataClone for OwnedArcRepr<A>
323{
324 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
325 {
326 (self.clone(), ptr)
328 }
329}
330
331unsafe impl<A> RawData for OwnedRepr<A>
332{
333 type Elem = A;
334
335 fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool
336 {
337 let slc = self.as_slice();
338 let ptr = slc.as_ptr() as *mut A;
339 let end = unsafe { ptr.add(slc.len()) };
340 self_ptr >= ptr && self_ptr <= end
341 }
342
343 private_impl! {}
344}
345
346unsafe impl<A> RawDataMut for OwnedRepr<A>
347{
348 #[inline]
349 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
350 where
351 Self: Sized,
352 D: Dimension,
353 {
354 }
355
356 #[inline]
357 fn try_is_unique(&mut self) -> Option<bool>
358 {
359 Some(true)
360 }
361}
362
363unsafe impl<A> Data for OwnedRepr<A>
364{
365 #[inline]
366 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
367 where
368 A: Clone,
369 D: Dimension,
370 {
371 self_
372 }
373
374 #[inline]
375 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
376 where D: Dimension
377 {
378 Ok(self_)
379 }
380}
381
382unsafe impl<A> DataMut for OwnedRepr<A> {}
383
384unsafe impl<A> RawDataClone for OwnedRepr<A>
385where A: Clone
386{
387 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
388 {
389 let mut u = self.clone();
390 let mut new_ptr = u.as_nonnull_mut();
391 if size_of::<A>() != 0 {
392 let our_off = (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
393 new_ptr = new_ptr.offset(our_off);
394 }
395 (u, new_ptr)
396 }
397
398 unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
399 {
400 let our_off = if size_of::<A>() != 0 {
401 (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
402 } else {
403 0
404 };
405 self.clone_from(other);
406 self.as_nonnull_mut().offset(our_off)
407 }
408}
409
410unsafe impl<'a, A> RawData for ViewRepr<&'a A>
411{
412 type Elem = A;
413
414 #[inline(always)]
415 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
416 {
417 true
418 }
419
420 private_impl! {}
421}
422
423unsafe impl<'a, A> Data for ViewRepr<&'a A>
424{
425 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
426 where
427 Self::Elem: Clone,
428 D: Dimension,
429 {
430 self_.to_owned()
431 }
432
433 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
434 where D: Dimension
435 {
436 Err(self_)
437 }
438}
439
440unsafe impl<'a, A> RawDataClone for ViewRepr<&'a A>
441{
442 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
443 {
444 (*self, ptr)
445 }
446}
447
448unsafe impl<'a, A> RawData for ViewRepr<&'a mut A>
449{
450 type Elem = A;
451
452 #[inline(always)]
453 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
454 {
455 true
456 }
457
458 private_impl! {}
459}
460
461unsafe impl<'a, A> RawDataMut for ViewRepr<&'a mut A>
462{
463 #[inline]
464 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
465 where
466 Self: Sized,
467 D: Dimension,
468 {
469 }
470
471 #[inline]
472 fn try_is_unique(&mut self) -> Option<bool>
473 {
474 Some(true)
475 }
476}
477
478unsafe impl<'a, A> Data for ViewRepr<&'a mut A>
479{
480 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
481 where
482 Self::Elem: Clone,
483 D: Dimension,
484 {
485 self_.to_owned()
486 }
487
488 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
489 where D: Dimension
490 {
491 Err(self_)
492 }
493}
494
495unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {}
496
497#[allow(clippy::missing_safety_doc)] pub unsafe trait DataOwned: Data
511{
512 type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>> + RawDataSubst<Self::Elem, Output = Self>;
514 #[doc(hidden)]
515 fn new(elements: Vec<Self::Elem>) -> Self;
516
517 #[doc(hidden)]
520 #[allow(clippy::wrong_self_convention)]
521 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
522 where
523 Self::Elem: Clone,
524 D: Dimension;
525}
526
527#[allow(clippy::missing_safety_doc)] pub unsafe trait DataShared: Clone + Data + RawDataClone {}
534
535unsafe impl<A> DataShared for OwnedArcRepr<A> {}
536unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
537
538unsafe impl<A> DataOwned for OwnedRepr<A>
539{
540 type MaybeUninit = OwnedRepr<MaybeUninit<A>>;
541
542 fn new(elements: Vec<A>) -> Self
543 {
544 OwnedRepr::from(elements)
545 }
546
547 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
548 where
549 A: Clone,
550 D: Dimension,
551 {
552 ArcArray::from(self_)
553 }
554}
555
556unsafe impl<A> DataOwned for OwnedArcRepr<A>
557{
558 type MaybeUninit = OwnedArcRepr<MaybeUninit<A>>;
559
560 fn new(elements: Vec<A>) -> Self
561 {
562 OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
563 }
564
565 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
566 where
567 A: Clone,
568 D: Dimension,
569 {
570 self_
571 }
572}
573
574unsafe impl<'a, A> RawData for CowRepr<'a, A>
575{
576 type Elem = A;
577
578 #[inline]
579 fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool
580 {
581 match self {
582 CowRepr::View(view) => view._is_pointer_inbounds(ptr),
583 CowRepr::Owned(data) => data._is_pointer_inbounds(ptr),
584 }
585 }
586
587 private_impl! {}
588}
589
590unsafe impl<'a, A> RawDataMut for CowRepr<'a, A>
591where A: Clone
592{
593 #[inline]
594 fn try_ensure_unique<D>(array: &mut ArrayBase<Self, D>)
595 where
596 Self: Sized,
597 D: Dimension,
598 {
599 match array.data {
600 CowRepr::View(_) => {
601 let owned = array.to_owned();
602 array.data = CowRepr::Owned(owned.data);
603 array.ptr = owned.ptr;
604 array.dim = owned.dim;
605 array.strides = owned.strides;
606 }
607 CowRepr::Owned(_) => {}
608 }
609 }
610
611 #[inline]
612 fn try_is_unique(&mut self) -> Option<bool>
613 {
614 Some(self.is_owned())
615 }
616}
617
618unsafe impl<'a, A> RawDataClone for CowRepr<'a, A>
619where A: Clone
620{
621 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
622 {
623 match self {
624 CowRepr::View(view) => {
625 let (new_view, ptr) = view.clone_with_ptr(ptr);
626 (CowRepr::View(new_view), ptr)
627 }
628 CowRepr::Owned(data) => {
629 let (new_data, ptr) = data.clone_with_ptr(ptr);
630 (CowRepr::Owned(new_data), ptr)
631 }
632 }
633 }
634
635 unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
636 {
637 match (&mut *self, other) {
638 (CowRepr::View(self_), CowRepr::View(other)) => self_.clone_from_with_ptr(other, ptr),
639 (CowRepr::Owned(self_), CowRepr::Owned(other)) => self_.clone_from_with_ptr(other, ptr),
640 (_, CowRepr::Owned(other)) => {
641 let (cloned, ptr) = other.clone_with_ptr(ptr);
642 *self = CowRepr::Owned(cloned);
643 ptr
644 }
645 (_, CowRepr::View(other)) => {
646 let (cloned, ptr) = other.clone_with_ptr(ptr);
647 *self = CowRepr::View(cloned);
648 ptr
649 }
650 }
651 }
652}
653
654unsafe impl<'a, A> Data for CowRepr<'a, A>
655{
656 #[inline]
657 fn into_owned<D>(self_: ArrayBase<CowRepr<'a, A>, D>) -> Array<Self::Elem, D>
658 where
659 A: Clone,
660 D: Dimension,
661 {
662 match self_.data {
663 CowRepr::View(_) => self_.to_owned(),
664 CowRepr::Owned(data) => unsafe {
665 ArrayBase::from_data_ptr(data, self_.ptr).with_strides_dim(self_.strides, self_.dim)
667 },
668 }
669 }
670
671 fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
672 where D: Dimension
673 {
674 match self_.data {
675 CowRepr::View(_) => Err(self_),
676 CowRepr::Owned(data) => unsafe {
677 Ok(ArrayBase::from_data_ptr(data, self_.ptr).with_strides_dim(self_.strides, self_.dim))
679 },
680 }
681 }
682}
683
684unsafe impl<'a, A> DataMut for CowRepr<'a, A> where A: Clone {}
685
686unsafe impl<'a, A> DataOwned for CowRepr<'a, A>
687{
688 type MaybeUninit = CowRepr<'a, MaybeUninit<A>>;
689
690 fn new(elements: Vec<A>) -> Self
691 {
692 CowRepr::Owned(OwnedRepr::new(elements))
693 }
694
695 fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
696 where
697 A: Clone,
698 D: Dimension,
699 {
700 self_.into_owned().into_shared()
701 }
702}
703
704pub trait RawDataSubst<A>: RawData
711{
712 type Output: RawData<Elem = A>;
714
715 unsafe fn data_subst(self) -> Self::Output;
722}
723
724impl<A, B> RawDataSubst<B> for OwnedRepr<A>
725{
726 type Output = OwnedRepr<B>;
727
728 unsafe fn data_subst(self) -> Self::Output
729 {
730 self.data_subst()
731 }
732}
733
734impl<A, B> RawDataSubst<B> for OwnedArcRepr<A>
735{
736 type Output = OwnedArcRepr<B>;
737
738 unsafe fn data_subst(self) -> Self::Output
739 {
740 OwnedArcRepr(Arc::from_raw(Arc::into_raw(self.0) as *const OwnedRepr<B>))
741 }
742}
743
744impl<A, B> RawDataSubst<B> for RawViewRepr<*const A>
745{
746 type Output = RawViewRepr<*const B>;
747
748 unsafe fn data_subst(self) -> Self::Output
749 {
750 RawViewRepr::new()
751 }
752}
753
754impl<A, B> RawDataSubst<B> for RawViewRepr<*mut A>
755{
756 type Output = RawViewRepr<*mut B>;
757
758 unsafe fn data_subst(self) -> Self::Output
759 {
760 RawViewRepr::new()
761 }
762}
763
764impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a A>
765{
766 type Output = ViewRepr<&'a B>;
767
768 unsafe fn data_subst(self) -> Self::Output
769 {
770 ViewRepr::new()
771 }
772}
773
774impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a mut A>
775{
776 type Output = ViewRepr<&'a mut B>;
777
778 unsafe fn data_subst(self) -> Self::Output
779 {
780 ViewRepr::new()
781 }
782}
783
784impl<'a, A: 'a, B: 'a> RawDataSubst<B> for CowRepr<'a, A>
785{
786 type Output = CowRepr<'a, B>;
787
788 unsafe fn data_subst(self) -> Self::Output
789 {
790 match self {
791 CowRepr::View(view) => CowRepr::View(view.data_subst()),
792 CowRepr::Owned(owned) => CowRepr::Owned(owned.data_subst()),
793 }
794 }
795}