ndarray/impl_views/
conversions.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
9use alloc::slice;
10#[allow(unused_imports)]
11use rawpointer::PointerExt;
12use std::mem::MaybeUninit;
13
14use crate::imp_prelude::*;
15
16use crate::{Baseiter, ElementsBase, ElementsBaseMut, Iter, IterMut};
17
18use crate::dimension::offset_from_low_addr_ptr_to_logical_ptr;
19use crate::iter::{self, AxisIter, AxisIterMut};
20use crate::math_cell::MathCell;
21use crate::IndexLonger;
22
23/// Methods for read-only array views.
24impl<'a, A, D> ArrayView<'a, A, D>
25where D: Dimension
26{
27    /// Convert the view into an `ArrayView<'b, A, D>` where `'b` is a lifetime
28    /// outlived by `'a'`.
29    pub fn reborrow<'b>(self) -> ArrayView<'b, A, D>
30    where 'a: 'b
31    {
32        unsafe { ArrayView::new(self.ptr, self.dim, self.strides) }
33    }
34
35    /// Return the array’s data as a slice, if it is contiguous and in standard order.
36    /// Return `None` otherwise.
37    ///
38    /// Note that while the method is similar to [`ArrayBase::as_slice()`], this method transfers
39    /// the view's lifetime to the slice, so it is a bit more powerful.
40    pub fn to_slice(&self) -> Option<&'a [A]>
41    {
42        if self.is_standard_layout() {
43            unsafe { Some(slice::from_raw_parts(self.ptr.as_ptr(), self.len())) }
44        } else {
45            None
46        }
47    }
48
49    /// Return the array’s data as a slice, if it is contiguous.
50    /// Return `None` otherwise.
51    ///
52    /// Note that while the method is similar to
53    /// [`ArrayBase::as_slice_memory_order()`], this method transfers the view's
54    /// lifetime to the slice, so it is a bit more powerful.
55    pub fn to_slice_memory_order(&self) -> Option<&'a [A]>
56    {
57        if self.is_contiguous() {
58            let offset = offset_from_low_addr_ptr_to_logical_ptr(&self.dim, &self.strides);
59            unsafe { Some(slice::from_raw_parts(self.ptr.sub(offset).as_ptr(), self.len())) }
60        } else {
61            None
62        }
63    }
64
65    /// Converts to a raw array view.
66    #[inline]
67    pub(crate) fn into_raw_view(self) -> RawArrayView<A, D>
68    {
69        unsafe { RawArrayView::new(self.ptr, self.dim, self.strides) }
70    }
71}
72
73/// Methods specific to `ArrayView0`.
74///
75/// ***See also all methods for [`ArrayView`] and [`ArrayBase`]***
76impl<'a, A> ArrayView<'a, A, Ix0>
77{
78    /// Consume the view and return a reference to the single element in the array.
79    ///
80    /// The lifetime of the returned reference matches the lifetime of the data
81    /// the array view was pointing to.
82    ///
83    /// ```
84    /// use ndarray::{arr0, Array0};
85    ///
86    /// // `Foo` doesn't implement `Clone`.
87    /// #[derive(Debug, Eq, PartialEq)]
88    /// struct Foo;
89    ///
90    /// let array: Array0<Foo> = arr0(Foo);
91    /// let view = array.view();
92    /// let scalar: &Foo = view.into_scalar();
93    /// assert_eq!(scalar, &Foo);
94    /// ```
95    pub fn into_scalar(self) -> &'a A
96    {
97        self.index(Ix0())
98    }
99}
100
101/// Methods specific to `ArrayViewMut0`.
102///
103/// ***See also all methods for [`ArrayViewMut`] and [`ArrayBase`]***
104impl<'a, A> ArrayViewMut<'a, A, Ix0>
105{
106    /// Consume the mutable view and return a mutable reference to the single element in the array.
107    ///
108    /// The lifetime of the returned reference matches the lifetime of the data
109    /// the array view was pointing to.
110    ///
111    /// ```
112    /// use ndarray::{arr0, Array0};
113    ///
114    /// let mut array: Array0<f64> = arr0(5.);
115    /// let view = array.view_mut();
116    /// let scalar = view.into_scalar();
117    /// *scalar = 7.;
118    /// assert_eq!(scalar, &7.);
119    /// assert_eq!(array[()], 7.);
120    /// ```
121    pub fn into_scalar(self) -> &'a mut A
122    {
123        self.index(Ix0())
124    }
125}
126
127/// Methods for read-write array views.
128impl<'a, A, D> ArrayViewMut<'a, A, D>
129where D: Dimension
130{
131    /// Return the array’s data as a slice, if it is contiguous and in standard order.
132    /// Return `None` otherwise.
133    ///
134    /// Note that while this is similar to [`ArrayBase::as_slice_mut()`], this method transfers the
135    /// view's lifetime to the slice.
136    pub fn into_slice(self) -> Option<&'a mut [A]>
137    {
138        self.try_into_slice().ok()
139    }
140
141    /// Return the array’s data as a slice, if it is contiguous.
142    /// Return `None` otherwise.
143    ///
144    /// Note that while this is similar to
145    /// [`ArrayBase::as_slice_memory_order_mut()`], this method transfers the
146    /// view's lifetime to the slice.
147    pub fn into_slice_memory_order(self) -> Option<&'a mut [A]>
148    {
149        self.try_into_slice_memory_order().ok()
150    }
151
152    /// Return a shared view of the array with elements as if they were embedded in cells.
153    ///
154    /// The cell view itself can be copied and accessed without exclusivity.
155    ///
156    /// The view acts "as if" the elements are temporarily in cells, and elements
157    /// can be changed through shared references using the regular cell methods.
158    pub fn into_cell_view(self) -> ArrayView<'a, MathCell<A>, D>
159    {
160        // safety: valid because
161        // A and MathCell<A> have the same representation
162        // &'a mut T is interchangeable with &'a Cell<T> -- see method Cell::from_mut in std
163        unsafe {
164            self.into_raw_view_mut()
165                .cast::<MathCell<A>>()
166                .deref_into_view()
167        }
168    }
169
170    /// Return the array view as a view of `MaybeUninit<A>` elements
171    ///
172    /// This conversion leaves the elements as they were (presumably initialized), but
173    /// they are represented with the `MaybeUninit<A>` type. Effectively this means that
174    /// the elements can be overwritten without dropping the old element in its place.
175    /// (In some situations this is not what you want, while for `Copy` elements it makes
176    /// no difference at all.)
177    ///
178    /// # Safety
179    ///
180    /// This method allows writing uninitialized data into the view, which could leave any
181    /// original array that we borrow from in an inconsistent state. This is not allowed
182    /// when using the resulting array view.
183    pub(crate) unsafe fn into_maybe_uninit(self) -> ArrayViewMut<'a, MaybeUninit<A>, D>
184    {
185        // Safe because: A and MaybeUninit<A> have the same representation;
186        // and we can go from initialized to (maybe) not unconditionally in terms of
187        // representation. However, the user must be careful to not write uninit elements
188        // through the view.
189        self.into_raw_view_mut()
190            .cast::<MaybeUninit<A>>()
191            .deref_into_view_mut()
192    }
193}
194
195/// Private raw array view methods
196impl<A, D> RawArrayView<A, D>
197where D: Dimension
198{
199    #[inline]
200    pub(crate) fn into_base_iter(self) -> Baseiter<A, D>
201    {
202        unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
203    }
204}
205
206impl<A, D> RawArrayViewMut<A, D>
207where D: Dimension
208{
209    #[inline]
210    pub(crate) fn into_base_iter(self) -> Baseiter<A, D>
211    {
212        unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
213    }
214}
215
216/// Private array view methods
217impl<'a, A, D> ArrayView<'a, A, D>
218where D: Dimension
219{
220    #[inline]
221    pub(crate) fn into_base_iter(self) -> Baseiter<A, D>
222    {
223        unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
224    }
225
226    #[inline]
227    pub(crate) fn into_elements_base(self) -> ElementsBase<'a, A, D>
228    {
229        ElementsBase::new(self)
230    }
231
232    pub(crate) fn into_iter_(self) -> Iter<'a, A, D>
233    {
234        Iter::new(self)
235    }
236
237    /// Return an outer iterator for this view.
238    #[doc(hidden)] // not official
239    #[deprecated(note = "This method will be replaced.")]
240    pub fn into_outer_iter(self) -> iter::AxisIter<'a, A, D::Smaller>
241    where D: RemoveAxis
242    {
243        AxisIter::new(self, Axis(0))
244    }
245}
246
247impl<'a, A, D> ArrayViewMut<'a, A, D>
248where D: Dimension
249{
250    // Convert into a read-only view
251    pub(crate) fn into_view(self) -> ArrayView<'a, A, D>
252    {
253        unsafe { ArrayView::new(self.ptr, self.dim, self.strides) }
254    }
255
256    /// Converts to a mutable raw array view.
257    pub(crate) fn into_raw_view_mut(self) -> RawArrayViewMut<A, D>
258    {
259        unsafe { RawArrayViewMut::new(self.ptr, self.dim, self.strides) }
260    }
261
262    #[inline]
263    pub(crate) fn into_base_iter(self) -> Baseiter<A, D>
264    {
265        unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
266    }
267
268    #[inline]
269    pub(crate) fn into_elements_base(self) -> ElementsBaseMut<'a, A, D>
270    {
271        ElementsBaseMut::new(self)
272    }
273
274    /// Return the array’s data as a slice, if it is contiguous and in standard order.
275    /// Otherwise return self in the Err branch of the result.
276    pub(crate) fn try_into_slice(self) -> Result<&'a mut [A], Self>
277    {
278        if self.is_standard_layout() {
279            unsafe { Ok(slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len())) }
280        } else {
281            Err(self)
282        }
283    }
284
285    /// Return the array’s data as a slice, if it is contiguous.
286    /// Otherwise return self in the Err branch of the result.
287    fn try_into_slice_memory_order(self) -> Result<&'a mut [A], Self>
288    {
289        if self.is_contiguous() {
290            let offset = offset_from_low_addr_ptr_to_logical_ptr(&self.dim, &self.strides);
291            unsafe { Ok(slice::from_raw_parts_mut(self.ptr.sub(offset).as_ptr(), self.len())) }
292        } else {
293            Err(self)
294        }
295    }
296
297    pub(crate) fn into_iter_(self) -> IterMut<'a, A, D>
298    {
299        IterMut::new(self)
300    }
301
302    /// Return an outer iterator for this view.
303    #[doc(hidden)] // not official
304    #[deprecated(note = "This method will be replaced.")]
305    pub fn into_outer_iter(self) -> iter::AxisIterMut<'a, A, D::Smaller>
306    where D: RemoveAxis
307    {
308        AxisIterMut::new(self, Axis(0))
309    }
310}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy