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
11use crate::imp_prelude::*;
12
13use crate::{Baseiter, ElementsBase, ElementsBaseMut, Iter, IterMut};
14
15use crate::iter::{self, AxisIter, AxisIterMut};
16use crate::math_cell::MathCell;
17use crate::IndexLonger;
18
19/// Methods for read-only array views.
20impl<'a, A, D> ArrayView<'a, A, D>
21where
22 D: Dimension,
23{
24 /// Convert the view into an `ArrayView<'b, A, D>` where `'b` is a lifetime
25 /// outlived by `'a'`.
26 pub fn reborrow<'b>(self) -> ArrayView<'b, A, D>
27 where
28 'a: 'b,
29 {
30 unsafe { ArrayView::new(self.ptr, self.dim, self.strides) }
31 }
32
33 /// Return the array’s data as a slice, if it is contiguous and in standard order.
34 /// Return `None` otherwise.
35 ///
36 /// Note that while the method is similar to [`ArrayBase::as_slice()`], this method tranfers
37 /// the view's lifetime to the slice, so it is a bit more powerful.
38 pub fn to_slice(&self) -> Option<&'a [A]> {
39 if self.is_standard_layout() {
40 unsafe { Some(slice::from_raw_parts(self.ptr.as_ptr(), self.len())) }
41 } else {
42 None
43 }
44 }
45
46 /// Converts to a raw array view.
47 pub(crate) fn into_raw_view(self) -> RawArrayView<A, D> {
48 unsafe { RawArrayView::new(self.ptr, self.dim, self.strides) }
49 }
50}
51
52/// Methods specific to `ArrayView0`.
53///
54/// ***See also all methods for [`ArrayView`] and [`ArrayBase`]***
55///
56/// [`ArrayBase`]: struct.ArrayBase.html
57/// [`ArrayView`]: struct.ArrayView.html
58impl<'a, A> ArrayView<'a, A, Ix0> {
59 /// Consume the view and return a reference to the single element in the array.
60 ///
61 /// The lifetime of the returned reference matches the lifetime of the data
62 /// the array view was pointing to.
63 ///
64 /// ```
65 /// use ndarray::{arr0, Array0};
66 ///
67 /// // `Foo` doesn't implement `Clone`.
68 /// #[derive(Debug, Eq, PartialEq)]
69 /// struct Foo;
70 ///
71 /// let array: Array0<Foo> = arr0(Foo);
72 /// let view = array.view();
73 /// let scalar: &Foo = view.into_scalar();
74 /// assert_eq!(scalar, &Foo);
75 /// ```
76 pub fn into_scalar(self) -> &'a A {
77 self.index(Ix0())
78 }
79}
80
81/// Methods specific to `ArrayViewMut0`.
82///
83/// ***See also all methods for [`ArrayViewMut`] and [`ArrayBase`]***
84///
85/// [`ArrayBase`]: struct.ArrayBase.html
86/// [`ArrayViewMut`]: struct.ArrayViewMut.html
87impl<'a, A> ArrayViewMut<'a, A, Ix0> {
88 /// Consume the mutable view and return a mutable reference to the single element in the array.
89 ///
90 /// The lifetime of the returned reference matches the lifetime of the data
91 /// the array view was pointing to.
92 ///
93 /// ```
94 /// use ndarray::{arr0, Array0};
95 ///
96 /// let mut array: Array0<f64> = arr0(5.);
97 /// let view = array.view_mut();
98 /// let mut scalar = view.into_scalar();
99 /// *scalar = 7.;
100 /// assert_eq!(scalar, &7.);
101 /// assert_eq!(array[()], 7.);
102 /// ```
103 pub fn into_scalar(self) -> &'a mut A {
104 self.index(Ix0())
105 }
106}
107
108/// Methods for read-write array views.
109impl<'a, A, D> ArrayViewMut<'a, A, D>
110where
111 D: Dimension,
112{
113 /// Return the array’s data as a slice, if it is contiguous and in standard order.
114 /// Return `None` otherwise.
115 ///
116 /// Note that while this is similar to [`ArrayBase::as_slice_mut()`], this method tranfers the
117 /// view's lifetime to the slice.
118 pub fn into_slice(self) -> Option<&'a mut [A]> {
119 self.try_into_slice().ok()
120 }
121
122 /// Return a shared view of the array with elements as if they were embedded in cells.
123 ///
124 /// The cell view itself can be copied and accessed without exclusivity.
125 ///
126 /// The view acts "as if" the elements are temporarily in cells, and elements
127 /// can be changed through shared references using the regular cell methods.
128 pub fn into_cell_view(self) -> ArrayView<'a, MathCell<A>, D> {
129 // safety: valid because
130 // A and MathCell<A> have the same representation
131 // &'a mut T is interchangeable with &'a Cell<T> -- see method Cell::from_mut in std
132 unsafe {
133 self.into_raw_view_mut().cast::<MathCell<A>>().deref_into_view()
134 }
135 }
136}
137
138/// Private array view methods
139impl<'a, A, D> ArrayView<'a, A, D>
140where
141 D: Dimension,
142{
143 #[inline]
144 pub(crate) fn into_base_iter(self) -> Baseiter<A, D> {
145 unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
146 }
147
148 #[inline]
149 pub(crate) fn into_elements_base(self) -> ElementsBase<'a, A, D> {
150 ElementsBase::new(self)
151 }
152
153 pub(crate) fn into_iter_(self) -> Iter<'a, A, D> {
154 Iter::new(self)
155 }
156
157 /// Return an outer iterator for this view.
158 #[doc(hidden)] // not official
159 #[deprecated(note = "This method will be replaced.")]
160 pub fn into_outer_iter(self) -> iter::AxisIter<'a, A, D::Smaller>
161 where
162 D: RemoveAxis,
163 {
164 AxisIter::new(self, Axis(0))
165 }
166}
167
168impl<'a, A, D> ArrayViewMut<'a, A, D>
169where
170 D: Dimension,
171{
172 // Convert into a read-only view
173 pub(crate) fn into_view(self) -> ArrayView<'a, A, D> {
174 unsafe { ArrayView::new(self.ptr, self.dim, self.strides) }
175 }
176
177 /// Converts to a mutable raw array view.
178 pub(crate) fn into_raw_view_mut(self) -> RawArrayViewMut<A, D> {
179 unsafe { RawArrayViewMut::new(self.ptr, self.dim, self.strides) }
180 }
181
182 #[inline]
183 pub(crate) fn into_base_iter(self) -> Baseiter<A, D> {
184 unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
185 }
186
187 #[inline]
188 pub(crate) fn into_elements_base(self) -> ElementsBaseMut<'a, A, D> {
189 ElementsBaseMut::new(self)
190 }
191
192 /// Return the array’s data as a slice, if it is contiguous and in standard order.
193 /// Otherwise return self in the Err branch of the result.
194 pub(crate) fn try_into_slice(self) -> Result<&'a mut [A], Self> {
195 if self.is_standard_layout() {
196 unsafe { Ok(slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len())) }
197 } else {
198 Err(self)
199 }
200 }
201
202 pub(crate) fn into_iter_(self) -> IterMut<'a, A, D> {
203 IterMut::new(self)
204 }
205
206 /// Return an outer iterator for this view.
207 #[doc(hidden)] // not official
208 #[deprecated(note = "This method will be replaced.")]
209 pub fn into_outer_iter(self) -> iter::AxisIterMut<'a, A, D::Smaller>
210 where
211 D: RemoveAxis,
212 {
213 AxisIterMut::new(self, Axis(0))
214 }
215}