ndarray/
data_traits.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! The data (inner representation) traits for ndarray
10
11use 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/// Array representation trait.
24///
25/// For an array that meets the invariants of the `ArrayBase` type. This trait
26/// does not imply any ownership or lifetime; pointers to elements in the array
27/// may not be safe to dereference.
28///
29/// ***Note:*** `RawData` is not an extension interface at this point.
30/// Traits in Rust can serve many different roles. This trait is public because
31/// it is used as a bound on public methods.
32#[allow(clippy::missing_safety_doc)] // not implementable downstream
33pub unsafe trait RawData: Sized {
34    /// The array element type.
35    type Elem;
36
37    #[doc(hidden)]
38    // This method is only used for debugging
39    #[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/// Array representation trait.
49///
50/// For an array with writable elements.
51///
52/// ***Internal trait, see `RawData`.***
53#[allow(clippy::missing_safety_doc)] // not implementable downstream
54pub unsafe trait RawDataMut: RawData {
55    /// If possible, ensures that the array has unique access to its data.
56    ///
57    /// The implementer must ensure that if the input is contiguous, then the
58    /// output has the same strides as input.
59    ///
60    /// Additionally, if `Self` provides safe mutable access to array elements,
61    /// then this method **must** panic or ensure that the data is unique.
62    #[doc(hidden)]
63    fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
64    where
65        Self: Sized,
66        D: Dimension;
67
68    /// If possible, returns whether the array has unique access to its data.
69    ///
70    /// If `Self` provides safe mutable access to array elements, then it
71    /// **must** return `Some(_)`.
72    #[doc(hidden)]
73    fn try_is_unique(&mut self) -> Option<bool>;
74}
75
76/// Array representation trait.
77///
78/// An array representation that can be cloned.
79///
80/// ***Internal trait, see `RawData`.***
81#[allow(clippy::missing_safety_doc)] // not implementable downstream
82pub unsafe trait RawDataClone: RawData {
83    #[doc(hidden)]
84    /// Unsafe because, `ptr` must point inside the current storage.
85    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/// Array representation trait.
100///
101/// For an array with elements that can be accessed with safe code.
102///
103/// ***Internal trait, see `RawData`.***
104#[allow(clippy::missing_safety_doc)] // not implementable downstream
105pub unsafe trait Data: RawData {
106    /// Converts the array to a uniquely owned array, cloning elements if necessary.
107    #[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    /// Converts the array into `Array<A, D>` if this is possible without
115    /// cloning the array elements. Otherwise, returns `self_` unchanged.
116    #[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    /// Return a shared ownership (copy on write) array based on the existing one,
124    /// cloning elements if necessary.
125    #[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        // clone to shared
133        self_.to_owned().into_shared()
134    }
135}
136
137/// Array representation trait.
138///
139/// For an array with writable elements that can be accessed with safe code.
140///
141/// ***Internal trait, see `Data`.***
142//
143// # For implementers
144//
145// If you implement the `DataMut` trait, you are guaranteeing that the
146// `RawDataMut::try_ensure_unique` implementation always panics or ensures that
147// the data is unique. You are also guaranteeing that `try_is_unique` always
148// returns `Some(_)`.
149#[allow(clippy::missing_safety_doc)] // not implementable downstream
150pub unsafe trait DataMut: Data + RawDataMut {
151    /// Ensures that the array has unique access to its data.
152    #[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    /// Returns whether the array has unique access to its data.
163    #[doc(hidden)]
164    #[inline]
165    #[allow(clippy::wrong_self_convention)]  // mut needed for Arc types
166    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
239// NOTE: Copy on write
240unsafe 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            // Clone only the visible elements if the current view is less than
254            // half of backing data.
255            *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        // safe because data is equivalent
285        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                // Safe because the data is equivalent.
300                Ok(ArrayBase::from_data_ptr(owned_data, self_.ptr)
301                    .with_strides_dim(self_.strides, self_.dim))
302            },
303            Err(arc_data) => unsafe {
304                // Safe because the data is equivalent; we're just
305                // reconstructing `self_`.
306                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        // to shared using clone of OwnedArcRepr without clone of raw data.
319        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        // pointer is preserved
328        (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/// Array representation trait.
507///
508/// A representation that is a unique or shared owner of its data.
509///
510/// ***Internal trait, see `Data`.***
511// The owned storage represents the ownership and allocation of the array's elements.
512// The storage may be unique or shared ownership style; it must be an aliasable owner
513// (permit aliasing pointers, such as our separate array head pointer).
514//
515// The array storage must be initially mutable - copy on write arrays may require copying for
516// unsharing storage before mutating it. The initially allocated storage must be mutable so
517// that it can be mutated directly - through .raw_view_mut_unchecked() - for initialization.
518#[allow(clippy::missing_safety_doc)] // not implementable downstream
519pub unsafe trait DataOwned: Data {
520    /// Corresponding owned data with MaybeUninit elements
521    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    /// Converts the data representation to a shared (copy on write)
527    /// representation, without any copying.
528    #[doc(hidden)]
529    fn into_shared(self) -> OwnedArcRepr<Self::Elem>;
530}
531
532/// Array representation trait.
533///
534/// A representation that is a lightweight view.
535///
536/// ***Internal trait, see `Data`.***
537#[allow(clippy::missing_safety_doc)] // not implementable downstream
538pub 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                // safe because the data is equivalent so ptr, dims remain valid
667                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                // safe because the data is equivalent so ptr, dims remain valid
683                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
692/// Array representation trait.
693///
694/// The RawDataSubst trait maps the element type of array storage, while
695/// keeping the same kind of storage.
696///
697/// For example, `RawDataSubst<B>` can map the type `OwnedRepr<A>` to `OwnedRepr<B>`.
698pub trait RawDataSubst<A>: RawData {
699    /// The resulting array storage of the same kind but substituted element type
700    type Output: RawData<Elem = A>;
701
702    /// Unsafely translate the data representation from one element
703    /// representation to another.
704    ///
705    /// ## Safety
706    ///
707    /// Caller must ensure the two types have the same representation.
708    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}