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::{ArrayBase, CowRepr, Dimension, OwnedArcRepr, OwnedRepr, RawViewRepr, ViewRepr};
20
21pub unsafe trait RawData: Sized {
31 type Elem;
33
34 #[doc(hidden)]
35 fn _data_slice(&self) -> Option<&[Self::Elem]>;
37
38 private_decl! {}
39}
40
41pub unsafe trait RawDataMut: RawData {
47 #[doc(hidden)]
52 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
53 where
54 Self: Sized,
55 D: Dimension;
56
57 #[doc(hidden)]
62 fn try_is_unique(&mut self) -> Option<bool>;
63}
64
65pub unsafe trait RawDataClone: RawData {
71 #[doc(hidden)]
72 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>);
74
75 #[doc(hidden)]
76 unsafe fn clone_from_with_ptr(
77 &mut self,
78 other: &Self,
79 ptr: NonNull<Self::Elem>,
80 ) -> NonNull<Self::Elem> {
81 let (data, ptr) = other.clone_with_ptr(ptr);
82 *self = data;
83 ptr
84 }
85}
86
87pub unsafe trait Data: RawData {
93 #[doc(hidden)]
95 #[allow(clippy::wrong_self_convention)]
96 fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
97 where
98 Self::Elem: Clone,
99 D: Dimension;
100
101 #[doc(hidden)]
104 #[allow(clippy::wrong_self_convention)]
105 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArrayBase<OwnedArcRepr<Self::Elem>, D>
106 where
107 Self::Elem: Clone,
108 D: Dimension,
109 {
110 self_.to_owned().into_shared()
112 }
113}
114
115pub unsafe trait DataMut: Data + RawDataMut {
128 #[doc(hidden)]
130 #[inline]
131 fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
132 where
133 Self: Sized,
134 D: Dimension,
135 {
136 Self::try_ensure_unique(self_)
137 }
138
139 #[doc(hidden)]
141 #[inline]
142 fn is_unique(&mut self) -> bool {
143 self.try_is_unique().unwrap()
144 }
145}
146
147unsafe impl<A> RawData for RawViewRepr<*const A> {
148 type Elem = A;
149 fn _data_slice(&self) -> Option<&[A]> {
150 None
151 }
152 private_impl! {}
153}
154
155unsafe impl<A> RawDataClone for RawViewRepr<*const A> {
156 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
157 (*self, ptr)
158 }
159}
160
161unsafe impl<A> RawData for RawViewRepr<*mut A> {
162 type Elem = A;
163 fn _data_slice(&self) -> Option<&[A]> {
164 None
165 }
166 private_impl! {}
167}
168
169unsafe impl<A> RawDataMut for RawViewRepr<*mut A> {
170 #[inline]
171 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
172 where
173 Self: Sized,
174 D: Dimension,
175 {
176 }
177
178 #[inline]
179 fn try_is_unique(&mut self) -> Option<bool> {
180 None
181 }
182}
183
184unsafe impl<A> RawDataClone for RawViewRepr<*mut A> {
185 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
186 (*self, ptr)
187 }
188}
189
190unsafe impl<A> RawData for OwnedArcRepr<A> {
191 type Elem = A;
192 fn _data_slice(&self) -> Option<&[A]> {
193 Some(self.0.as_slice())
194 }
195 private_impl! {}
196}
197
198unsafe impl<A> RawDataMut for OwnedArcRepr<A>
200where
201 A: Clone,
202{
203 fn try_ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
204 where
205 Self: Sized,
206 D: Dimension,
207 {
208 if Arc::get_mut(&mut self_.data.0).is_some() {
209 return;
210 }
211 if self_.dim.size() <= self_.data.0.len() / 2 {
212 unsafe {
215 *self_ = ArrayBase::from_shape_vec_unchecked(
216 self_.dim.clone(),
217 self_.iter().cloned().collect(),
218 );
219 }
220 return;
221 }
222 let rcvec = &mut self_.data.0;
223 let a_size = mem::size_of::<A>() as isize;
224 let our_off = if a_size != 0 {
225 (self_.ptr.as_ptr() as isize - rcvec.as_ptr() as isize) / a_size
226 } else {
227 0
228 };
229 let rvec = Arc::make_mut(rcvec);
230 unsafe {
231 self_.ptr = rvec.as_nonnull_mut().offset(our_off);
232 }
233 }
234
235 fn try_is_unique(&mut self) -> Option<bool> {
236 Some(Arc::get_mut(&mut self.0).is_some())
237 }
238}
239
240unsafe impl<A> Data for OwnedArcRepr<A> {
241 fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
242 where
243 A: Clone,
244 D: Dimension,
245 {
246 Self::ensure_unique(&mut self_);
247 let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
248 unsafe {
250 ArrayBase::from_data_ptr(data, self_.ptr)
251 .with_strides_dim(self_.strides, self_.dim)
252 }
253 }
254
255 fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArrayBase<OwnedArcRepr<Self::Elem>, D>
256 where
257 Self::Elem: Clone,
258 D: Dimension,
259 {
260 self_.clone()
262 }
263}
264
265unsafe impl<A> DataMut for OwnedArcRepr<A> where A: Clone {}
266
267unsafe impl<A> RawDataClone for OwnedArcRepr<A> {
268 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
269 (self.clone(), ptr)
271 }
272}
273
274unsafe impl<A> RawData for OwnedRepr<A> {
275 type Elem = A;
276 fn _data_slice(&self) -> Option<&[A]> {
277 Some(self.as_slice())
278 }
279 private_impl! {}
280}
281
282unsafe impl<A> RawDataMut for OwnedRepr<A> {
283 #[inline]
284 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
285 where
286 Self: Sized,
287 D: Dimension,
288 {
289 }
290
291 #[inline]
292 fn try_is_unique(&mut self) -> Option<bool> {
293 Some(true)
294 }
295}
296
297unsafe impl<A> Data for OwnedRepr<A> {
298 #[inline]
299 fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
300 where
301 A: Clone,
302 D: Dimension,
303 {
304 self_
305 }
306}
307
308unsafe impl<A> DataMut for OwnedRepr<A> {}
309
310unsafe impl<A> RawDataClone for OwnedRepr<A>
311where
312 A: Clone,
313{
314 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
315 let mut u = self.clone();
316 let mut new_ptr = u.as_nonnull_mut();
317 if size_of::<A>() != 0 {
318 let our_off =
319 (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
320 new_ptr = new_ptr.offset(our_off);
321 }
322 (u, new_ptr)
323 }
324
325 unsafe fn clone_from_with_ptr(
326 &mut self,
327 other: &Self,
328 ptr: NonNull<Self::Elem>,
329 ) -> NonNull<Self::Elem> {
330 let our_off = if size_of::<A>() != 0 {
331 (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
332 } else {
333 0
334 };
335 self.clone_from(&other);
336 self.as_nonnull_mut().offset(our_off)
337 }
338}
339
340unsafe impl<'a, A> RawData for ViewRepr<&'a A> {
341 type Elem = A;
342 fn _data_slice(&self) -> Option<&[A]> {
343 None
344 }
345 private_impl! {}
346}
347
348unsafe impl<'a, A> Data for ViewRepr<&'a A> {
349 fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
350 where
351 Self::Elem: Clone,
352 D: Dimension,
353 {
354 self_.to_owned()
355 }
356}
357
358unsafe impl<'a, A> RawDataClone for ViewRepr<&'a A> {
359 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
360 (*self, ptr)
361 }
362}
363
364unsafe impl<'a, A> RawData for ViewRepr<&'a mut A> {
365 type Elem = A;
366 fn _data_slice(&self) -> Option<&[A]> {
367 None
368 }
369 private_impl! {}
370}
371
372unsafe impl<'a, A> RawDataMut for ViewRepr<&'a mut A> {
373 #[inline]
374 fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
375 where
376 Self: Sized,
377 D: Dimension,
378 {
379 }
380
381 #[inline]
382 fn try_is_unique(&mut self) -> Option<bool> {
383 Some(true)
384 }
385}
386
387unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
388 fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
389 where
390 Self::Elem: Clone,
391 D: Dimension,
392 {
393 self_.to_owned()
394 }
395}
396
397unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {}
398
399pub unsafe trait DataOwned: Data {
412 type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>>
414 + RawDataSubst<Self::Elem, Output=Self>;
415 #[doc(hidden)]
416 fn new(elements: Vec<Self::Elem>) -> Self;
417
418 #[doc(hidden)]
421 fn into_shared(self) -> OwnedArcRepr<Self::Elem>;
422}
423
424pub unsafe trait DataShared: Clone + Data + RawDataClone {}
430
431unsafe impl<A> DataShared for OwnedArcRepr<A> {}
432unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
433
434unsafe impl<A> DataOwned for OwnedRepr<A> {
435 type MaybeUninit = OwnedRepr<MaybeUninit<A>>;
436
437 fn new(elements: Vec<A>) -> Self {
438 OwnedRepr::from(elements)
439 }
440
441 fn into_shared(self) -> OwnedArcRepr<A> {
442 OwnedArcRepr(Arc::new(self))
443 }
444}
445
446unsafe impl<A> DataOwned for OwnedArcRepr<A> {
447 type MaybeUninit = OwnedArcRepr<MaybeUninit<A>>;
448
449 fn new(elements: Vec<A>) -> Self {
450 OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
451 }
452
453 fn into_shared(self) -> OwnedArcRepr<A> {
454 self
455 }
456}
457
458unsafe impl<'a, A> RawData for CowRepr<'a, A> {
459 type Elem = A;
460 fn _data_slice(&self) -> Option<&[A]> {
461 match self {
462 CowRepr::View(view) => view._data_slice(),
463 CowRepr::Owned(data) => data._data_slice(),
464 }
465 }
466 private_impl! {}
467}
468
469unsafe impl<'a, A> RawDataMut for CowRepr<'a, A>
470where
471 A: Clone,
472{
473 #[inline]
474 fn try_ensure_unique<D>(array: &mut ArrayBase<Self, D>)
475 where
476 Self: Sized,
477 D: Dimension,
478 {
479 match array.data {
480 CowRepr::View(_) => {
481 let owned = array.to_owned();
482 array.data = CowRepr::Owned(owned.data);
483 array.ptr = owned.ptr;
484 array.dim = owned.dim;
485 array.strides = owned.strides;
486 }
487 CowRepr::Owned(_) => {}
488 }
489 }
490
491 #[inline]
492 fn try_is_unique(&mut self) -> Option<bool> {
493 Some(self.is_owned())
494 }
495}
496
497unsafe impl<'a, A> RawDataClone for CowRepr<'a, A>
498where
499 A: Clone,
500{
501 unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
502 match self {
503 CowRepr::View(view) => {
504 let (new_view, ptr) = view.clone_with_ptr(ptr);
505 (CowRepr::View(new_view), ptr)
506 }
507 CowRepr::Owned(data) => {
508 let (new_data, ptr) = data.clone_with_ptr(ptr);
509 (CowRepr::Owned(new_data), ptr)
510 }
511 }
512 }
513
514 #[doc(hidden)]
515 unsafe fn clone_from_with_ptr(
516 &mut self,
517 other: &Self,
518 ptr: NonNull<Self::Elem>,
519 ) -> NonNull<Self::Elem> {
520 match (&mut *self, other) {
521 (CowRepr::View(self_), CowRepr::View(other)) => self_.clone_from_with_ptr(other, ptr),
522 (CowRepr::Owned(self_), CowRepr::Owned(other)) => self_.clone_from_with_ptr(other, ptr),
523 (_, CowRepr::Owned(other)) => {
524 let (cloned, ptr) = other.clone_with_ptr(ptr);
525 *self = CowRepr::Owned(cloned);
526 ptr
527 }
528 (_, CowRepr::View(other)) => {
529 let (cloned, ptr) = other.clone_with_ptr(ptr);
530 *self = CowRepr::View(cloned);
531 ptr
532 }
533 }
534 }
535}
536
537unsafe impl<'a, A> Data for CowRepr<'a, A> {
538 #[inline]
539 fn into_owned<D>(self_: ArrayBase<CowRepr<'a, A>, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
540 where
541 A: Clone,
542 D: Dimension,
543 {
544 match self_.data {
545 CowRepr::View(_) => self_.to_owned(),
546 CowRepr::Owned(data) => unsafe {
547 ArrayBase::from_data_ptr(data, self_.ptr)
549 .with_strides_dim(self_.strides, self_.dim)
550 },
551 }
552 }
553}
554
555unsafe impl<'a, A> DataMut for CowRepr<'a, A> where A: Clone {}
556
557pub trait RawDataSubst<A>: RawData {
564 type Output: RawData<Elem = A>;
566
567 unsafe fn data_subst(self) -> Self::Output;
574}
575
576impl<A, B> RawDataSubst<B> for OwnedRepr<A> {
577 type Output = OwnedRepr<B>;
578
579 unsafe fn data_subst(self) -> Self::Output {
580 self.data_subst()
581 }
582}
583
584impl<A, B> RawDataSubst<B> for OwnedArcRepr<A> {
585 type Output = OwnedArcRepr<B>;
586
587 unsafe fn data_subst(self) -> Self::Output {
588 OwnedArcRepr(Arc::from_raw(Arc::into_raw(self.0) as *const OwnedRepr<B>))
589 }
590}
591
592impl<A, B> RawDataSubst<B> for RawViewRepr<*const A> {
593 type Output = RawViewRepr<*const B>;
594
595 unsafe fn data_subst(self) -> Self::Output {
596 RawViewRepr::new()
597 }
598}
599
600impl<A, B> RawDataSubst<B> for RawViewRepr<*mut A> {
601 type Output = RawViewRepr<*mut B>;
602
603 unsafe fn data_subst(self) -> Self::Output {
604 RawViewRepr::new()
605 }
606}
607
608impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a A> {
609 type Output = ViewRepr<&'a B>;
610
611 unsafe fn data_subst(self) -> Self::Output {
612 ViewRepr::new()
613 }
614}
615
616impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a mut A> {
617 type Output = ViewRepr<&'a mut B>;
618
619 unsafe fn data_subst(self) -> Self::Output {
620 ViewRepr::new()
621 }
622}
623