1use rawpointer::PointerExt;
12
13use std::mem::{self, size_of};
14use std::mem::MaybeUninit;
15use std::ptr::NonNull;
16use alloc::sync::Arc;
17use alloc::vec::Vec;
18
19use crate::{
20 ArcArray, Array, ArrayBase, CowRepr, Dimension, OwnedArcRepr, OwnedRepr, RawViewRepr, ViewRepr,
21};
22
23#[allow(clippy::missing_safety_doc)] pub unsafe trait RawData: Sized {
34 type Elem;
36
37 #[doc(hidden)]
38 #[deprecated(note="Unused", since="0.15.2")]
40 fn _data_slice(&self) -> Option<&[Self::Elem]>;
41
42 #[doc(hidden)]
43 fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool;
44
45 private_decl! {}
46}
47
48#[allow(clippy::missing_safety_doc)] pub unsafe trait RawDataMut: RawData {
55 #[doc(hidden)]
63 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
64 where
65 Self: Sized,
66 D: Dimension;
67
68 #[doc(hidden)]
73 fn try_is_unique(&mut self) -> Option<bool>;
74}
75
76#[allow(clippy::missing_safety_doc)] pub unsafe trait RawDataClone: RawData {
83 #[doc(hidden)]
84 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>);
86
87 #[doc(hidden)]
88 unsafe fn clone_from_with_ptr(
89 &mut self,
90 other: &Self,
91 ptr: NonNull<Self::Elem>,
92 ) -> NonNull<Self::Elem> {
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 #[doc(hidden)]
108 #[allow(clippy::wrong_self_convention)]
109 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
110 where
111 Self::Elem: Clone,
112 D: Dimension;
113
114 #[doc(hidden)]
117 fn try_into_owned_nocopy<D>(
118 self_: ArrayBase<Self, D>,
119 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
120 where
121 D: Dimension;
122
123 #[doc(hidden)]
126 #[allow(clippy::wrong_self_convention)]
127 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
128 where
129 Self::Elem: Clone,
130 D: Dimension,
131 {
132 self_.to_owned().into_shared()
134 }
135}
136
137#[allow(clippy::missing_safety_doc)] pub unsafe trait DataMut: Data + RawDataMut {
151 #[doc(hidden)]
153 #[inline]
154 fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
155 where
156 Self: Sized,
157 D: Dimension,
158 {
159 Self::try_ensure_unique(self_)
160 }
161
162 #[doc(hidden)]
164 #[inline]
165 #[allow(clippy::wrong_self_convention)] fn is_unique(&mut self) -> bool {
167 self.try_is_unique().unwrap()
168 }
169}
170
171unsafe impl<A> RawData for RawViewRepr<*const A> {
172 type Elem = A;
173
174 #[inline]
175 fn _data_slice(&self) -> Option<&[A]> {
176 None
177 }
178
179 #[inline(always)]
180 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool { true }
181
182 private_impl! {}
183}
184
185unsafe impl<A> RawDataClone for RawViewRepr<*const A> {
186 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
187 (*self, ptr)
188 }
189}
190
191unsafe impl<A> RawData for RawViewRepr<*mut A> {
192 type Elem = A;
193
194 #[inline]
195 fn _data_slice(&self) -> Option<&[A]> {
196 None
197 }
198
199 #[inline(always)]
200 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool { true }
201
202 private_impl! {}
203}
204
205unsafe impl<A> RawDataMut for RawViewRepr<*mut A> {
206 #[inline]
207 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
208 where
209 Self: Sized,
210 D: Dimension,
211 {
212 }
213
214 #[inline]
215 fn try_is_unique(&mut self) -> Option<bool> {
216 None
217 }
218}
219
220unsafe impl<A> RawDataClone for RawViewRepr<*mut A> {
221 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
222 (*self, ptr)
223 }
224}
225
226unsafe impl<A> RawData for OwnedArcRepr<A> {
227 type Elem = A;
228 fn _data_slice(&self) -> Option<&[A]> {
229 Some(self.0.as_slice())
230 }
231
232 fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool {
233 self.0._is_pointer_inbounds(self_ptr)
234 }
235
236 private_impl! {}
237}
238
239unsafe impl<A> RawDataMut for OwnedArcRepr<A>
241where
242 A: Clone,
243{
244 fn try_ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
245 where
246 Self: Sized,
247 D: Dimension,
248 {
249 if Arc::get_mut(&mut self_.data.0).is_some() {
250 return;
251 }
252 if self_.dim.size() <= self_.data.0.len() / 2 {
253 *self_ = self_.to_owned().into_shared();
256 return;
257 }
258 let rcvec = &mut self_.data.0;
259 let a_size = mem::size_of::<A>() as isize;
260 let our_off = if a_size != 0 {
261 (self_.ptr.as_ptr() as isize - rcvec.as_ptr() as isize) / a_size
262 } else {
263 0
264 };
265 let rvec = Arc::make_mut(rcvec);
266 unsafe {
267 self_.ptr = rvec.as_nonnull_mut().offset(our_off);
268 }
269 }
270
271 fn try_is_unique(&mut self) -> Option<bool> {
272 Some(Arc::get_mut(&mut self.0).is_some())
273 }
274}
275
276unsafe impl<A> Data for OwnedArcRepr<A> {
277 fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
278 where
279 A: Clone,
280 D: Dimension,
281 {
282 Self::ensure_unique(&mut self_);
283 let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
284 unsafe {
286 ArrayBase::from_data_ptr(data, self_.ptr)
287 .with_strides_dim(self_.strides, self_.dim)
288 }
289 }
290
291 fn try_into_owned_nocopy<D>(
292 self_: ArrayBase<Self, D>,
293 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
294 where
295 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_.ptr)
301 .with_strides_dim(self_.strides, self_.dim))
302 },
303 Err(arc_data) => unsafe {
304 Err(ArrayBase::from_data_ptr(OwnedArcRepr(arc_data), self_.ptr)
307 .with_strides_dim(self_.strides, self_.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 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
327 (self.clone(), ptr)
329 }
330}
331
332unsafe impl<A> RawData for OwnedRepr<A> {
333 type Elem = A;
334
335 fn _data_slice(&self) -> Option<&[A]> {
336 Some(self.as_slice())
337 }
338
339 fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool {
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 #[inline]
351 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
352 where
353 Self: Sized,
354 D: Dimension,
355 {
356 }
357
358 #[inline]
359 fn try_is_unique(&mut self) -> Option<bool> {
360 Some(true)
361 }
362}
363
364unsafe impl<A> Data for OwnedRepr<A> {
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>(
376 self_: ArrayBase<Self, D>,
377 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
378 where
379 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
389 A: Clone,
390{
391 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
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 =
396 (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
397 new_ptr = new_ptr.offset(our_off);
398 }
399 (u, new_ptr)
400 }
401
402 unsafe fn clone_from_with_ptr(
403 &mut self,
404 other: &Self,
405 ptr: NonNull<Self::Elem>,
406 ) -> NonNull<Self::Elem> {
407 let our_off = if size_of::<A>() != 0 {
408 (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
409 } else {
410 0
411 };
412 self.clone_from(other);
413 self.as_nonnull_mut().offset(our_off)
414 }
415}
416
417unsafe impl<'a, A> RawData for ViewRepr<&'a A> {
418 type Elem = A;
419
420 #[inline]
421 fn _data_slice(&self) -> Option<&[A]> {
422 None
423 }
424
425 #[inline(always)]
426 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool { true }
427
428 private_impl! {}
429}
430
431unsafe impl<'a, A> Data for ViewRepr<&'a A> {
432 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
433 where
434 Self::Elem: Clone,
435 D: Dimension,
436 {
437 self_.to_owned()
438 }
439
440 fn try_into_owned_nocopy<D>(
441 self_: ArrayBase<Self, D>,
442 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
443 where
444 D: Dimension,
445 {
446 Err(self_)
447 }
448}
449
450unsafe impl<'a, A> RawDataClone for ViewRepr<&'a A> {
451 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
452 (*self, ptr)
453 }
454}
455
456unsafe impl<'a, A> RawData for ViewRepr<&'a mut A> {
457 type Elem = A;
458
459 #[inline]
460 fn _data_slice(&self) -> Option<&[A]> {
461 None
462 }
463
464 #[inline(always)]
465 fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool { true }
466
467 private_impl! {}
468}
469
470unsafe impl<'a, A> RawDataMut for ViewRepr<&'a mut A> {
471 #[inline]
472 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
473 where
474 Self: Sized,
475 D: Dimension,
476 {
477 }
478
479 #[inline]
480 fn try_is_unique(&mut self) -> Option<bool> {
481 Some(true)
482 }
483}
484
485unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
486 fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
487 where
488 Self::Elem: Clone,
489 D: Dimension,
490 {
491 self_.to_owned()
492 }
493
494 fn try_into_owned_nocopy<D>(
495 self_: ArrayBase<Self, D>,
496 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
497 where
498 D: Dimension,
499 {
500 Err(self_)
501 }
502}
503
504unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {}
505
506#[allow(clippy::missing_safety_doc)] pub unsafe trait DataOwned: Data {
520 type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>>
522 + RawDataSubst<Self::Elem, Output=Self>;
523 #[doc(hidden)]
524 fn new(elements: Vec<Self::Elem>) -> Self;
525
526 #[doc(hidden)]
529 fn into_shared(self) -> OwnedArcRepr<Self::Elem>;
530}
531
532#[allow(clippy::missing_safety_doc)] pub unsafe trait DataShared: Clone + Data + RawDataClone {}
539
540unsafe impl<A> DataShared for OwnedArcRepr<A> {}
541unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
542
543unsafe impl<A> DataOwned for OwnedRepr<A> {
544 type MaybeUninit = OwnedRepr<MaybeUninit<A>>;
545
546 fn new(elements: Vec<A>) -> Self {
547 OwnedRepr::from(elements)
548 }
549
550 fn into_shared(self) -> OwnedArcRepr<A> {
551 OwnedArcRepr(Arc::new(self))
552 }
553}
554
555unsafe impl<A> DataOwned for OwnedArcRepr<A> {
556 type MaybeUninit = OwnedArcRepr<MaybeUninit<A>>;
557
558 fn new(elements: Vec<A>) -> Self {
559 OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
560 }
561
562 fn into_shared(self) -> OwnedArcRepr<A> {
563 self
564 }
565}
566
567unsafe impl<'a, A> RawData for CowRepr<'a, A> {
568 type Elem = A;
569
570 fn _data_slice(&self) -> Option<&[A]> {
571 #[allow(deprecated)]
572 match self {
573 CowRepr::View(view) => view._data_slice(),
574 CowRepr::Owned(data) => data._data_slice(),
575 }
576 }
577
578 #[inline]
579 fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool {
580 match self {
581 CowRepr::View(view) => view._is_pointer_inbounds(ptr),
582 CowRepr::Owned(data) => data._is_pointer_inbounds(ptr),
583 }
584 }
585
586 private_impl! {}
587}
588
589unsafe impl<'a, A> RawDataMut for CowRepr<'a, A>
590where
591 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 Some(self.is_owned())
614 }
615}
616
617unsafe impl<'a, A> RawDataClone for CowRepr<'a, A>
618where
619 A: Clone,
620{
621 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
622 match self {
623 CowRepr::View(view) => {
624 let (new_view, ptr) = view.clone_with_ptr(ptr);
625 (CowRepr::View(new_view), ptr)
626 }
627 CowRepr::Owned(data) => {
628 let (new_data, ptr) = data.clone_with_ptr(ptr);
629 (CowRepr::Owned(new_data), ptr)
630 }
631 }
632 }
633
634 unsafe fn clone_from_with_ptr(
635 &mut self,
636 other: &Self,
637 ptr: NonNull<Self::Elem>,
638 ) -> NonNull<Self::Elem> {
639 match (&mut *self, other) {
640 (CowRepr::View(self_), CowRepr::View(other)) => self_.clone_from_with_ptr(other, ptr),
641 (CowRepr::Owned(self_), CowRepr::Owned(other)) => self_.clone_from_with_ptr(other, ptr),
642 (_, CowRepr::Owned(other)) => {
643 let (cloned, ptr) = other.clone_with_ptr(ptr);
644 *self = CowRepr::Owned(cloned);
645 ptr
646 }
647 (_, CowRepr::View(other)) => {
648 let (cloned, ptr) = other.clone_with_ptr(ptr);
649 *self = CowRepr::View(cloned);
650 ptr
651 }
652 }
653 }
654}
655
656unsafe impl<'a, A> Data for CowRepr<'a, A> {
657 #[inline]
658 fn into_owned<D>(self_: ArrayBase<CowRepr<'a, A>, D>) -> Array<Self::Elem, D>
659 where
660 A: Clone,
661 D: Dimension,
662 {
663 match self_.data {
664 CowRepr::View(_) => self_.to_owned(),
665 CowRepr::Owned(data) => unsafe {
666 ArrayBase::from_data_ptr(data, self_.ptr)
668 .with_strides_dim(self_.strides, self_.dim)
669 },
670 }
671 }
672
673 fn try_into_owned_nocopy<D>(
674 self_: ArrayBase<Self, D>,
675 ) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
676 where
677 D: Dimension,
678 {
679 match self_.data {
680 CowRepr::View(_) => Err(self_),
681 CowRepr::Owned(data) => unsafe {
682 Ok(ArrayBase::from_data_ptr(data, self_.ptr)
684 .with_strides_dim(self_.strides, self_.dim))
685 },
686 }
687 }
688}
689
690unsafe impl<'a, A> DataMut for CowRepr<'a, A> where A: Clone {}
691
692pub trait RawDataSubst<A>: RawData {
699 type Output: RawData<Elem = A>;
701
702 unsafe fn data_subst(self) -> Self::Output;
709}
710
711impl<A, B> RawDataSubst<B> for OwnedRepr<A> {
712 type Output = OwnedRepr<B>;
713
714 unsafe fn data_subst(self) -> Self::Output {
715 self.data_subst()
716 }
717}
718
719impl<A, B> RawDataSubst<B> for OwnedArcRepr<A> {
720 type Output = OwnedArcRepr<B>;
721
722 unsafe fn data_subst(self) -> Self::Output {
723 OwnedArcRepr(Arc::from_raw(Arc::into_raw(self.0) as *const OwnedRepr<B>))
724 }
725}
726
727impl<A, B> RawDataSubst<B> for RawViewRepr<*const A> {
728 type Output = RawViewRepr<*const B>;
729
730 unsafe fn data_subst(self) -> Self::Output {
731 RawViewRepr::new()
732 }
733}
734
735impl<A, B> RawDataSubst<B> for RawViewRepr<*mut A> {
736 type Output = RawViewRepr<*mut B>;
737
738 unsafe fn data_subst(self) -> Self::Output {
739 RawViewRepr::new()
740 }
741}
742
743impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a A> {
744 type Output = ViewRepr<&'a B>;
745
746 unsafe fn data_subst(self) -> Self::Output {
747 ViewRepr::new()
748 }
749}
750
751impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a mut A> {
752 type Output = ViewRepr<&'a mut B>;
753
754 unsafe fn data_subst(self) -> Self::Output {
755 ViewRepr::new()
756 }
757}
758
759impl<'a, A: 'a, B: 'a> RawDataSubst<B> for CowRepr<'a, A> {
760 type Output = CowRepr<'a, B>;
761
762 unsafe fn data_subst(self) -> Self::Output {
763 match self {
764 CowRepr::View(view) => CowRepr::View(view.data_subst()),
765 CowRepr::Owned(owned) => CowRepr::Owned(owned.data_subst()),
766 }
767 }
768}