Skip to content

Commit f6fd4be

Browse files
jturner314bluss
authored andcommitted
Make aview* free functions be const fns
1 parent 62461d7 commit f6fd4be

File tree

1 file changed

+83
-9
lines changed

1 file changed

+83
-9
lines changed

src/free_functions.rs

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use alloc::vec;
1010
#[cfg(not(feature = "std"))]
1111
use alloc::vec::Vec;
1212
use std::mem::{forget, size_of};
13+
use std::ptr::NonNull;
1314

1415
use crate::imp_prelude::*;
1516
use crate::{dimension, ArcArray1, ArcArray2};
@@ -65,32 +66,105 @@ pub fn rcarr1<A: Clone>(xs: &[A]) -> ArcArray1<A> {
6566
}
6667

6768
/// Create a zero-dimensional array view borrowing `x`.
68-
pub fn aview0<A>(x: &A) -> ArrayView0<'_, A> {
69-
unsafe { ArrayView::from_shape_ptr(Ix0(), x) }
69+
pub const fn aview0<A>(x: &A) -> ArrayView0<'_, A> {
70+
ArrayBase {
71+
data: ViewRepr::new(),
72+
// Safe because references are always non-null.
73+
ptr: unsafe { NonNull::new_unchecked(x as *const A as *mut A) },
74+
dim: Ix0(),
75+
strides: Ix0(),
76+
}
7077
}
7178

7279
/// Create a one-dimensional array view with elements borrowing `xs`.
7380
///
81+
/// **Panics** if the length of the slice overflows `isize`. (This can only
82+
/// occur if `A` is zero-sized, because slices cannot contain more than
83+
/// `isize::MAX` number of bytes.)
84+
///
7485
/// ```
75-
/// use ndarray::aview1;
86+
/// use ndarray::{aview1, ArrayView1};
7687
///
7788
/// let data = [1.0; 1024];
7889
///
7990
/// // Create a 2D array view from borrowed data
8091
/// let a2d = aview1(&data).into_shape((32, 32)).unwrap();
8192
///
8293
/// assert_eq!(a2d.sum(), 1024.0);
94+
///
95+
/// // Create a const 1D array view
96+
/// const C: ArrayView1<'static, f64> = aview1(&[1., 2., 3.]);
97+
///
98+
/// assert_eq!(C.sum(), 6.);
8399
/// ```
84-
pub fn aview1<A>(xs: &[A]) -> ArrayView1<'_, A> {
85-
ArrayView::from(xs)
100+
pub const fn aview1<A>(xs: &[A]) -> ArrayView1<'_, A> {
101+
if size_of::<A>() == 0 {
102+
assert!(
103+
xs.len() <= isize::MAX as usize,
104+
"Slice length must fit in `isize`.",
105+
);
106+
}
107+
ArrayBase {
108+
data: ViewRepr::new(),
109+
// Safe because references are always non-null.
110+
ptr: unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) },
111+
dim: Ix1(xs.len()),
112+
strides: Ix1(1),
113+
}
86114
}
87115

88116
/// Create a two-dimensional array view with elements borrowing `xs`.
89117
///
90-
/// **Panics** if the product of non-zero axis lengths overflows `isize` (This can only occur if A
91-
/// is zero-sized because slices cannot contain more than `isize::MAX` number of bytes).
92-
pub fn aview2<A, const N: usize>(xs: &[[A; N]]) -> ArrayView2<'_, A> {
93-
ArrayView2::from(xs)
118+
/// **Panics** if the product of non-zero axis lengths overflows `isize` (This
119+
/// can only occur if A is zero-sized or if `N` is zero, because slices cannot
120+
/// contain more than `isize::MAX` number of bytes).
121+
///
122+
/// ```
123+
/// use ndarray::{aview2, ArrayView2};
124+
///
125+
/// let data = vec![[1., 2., 3.], [4., 5., 6.]];
126+
///
127+
/// let view = aview2(&data);
128+
/// assert_eq!(view.sum(), 21.);
129+
///
130+
/// // Create a const 2D array view
131+
/// const C: ArrayView2<'static, f64> = aview2(&[[1., 2., 3.], [4., 5., 6.]]);
132+
/// assert_eq!(C.sum(), 21.);
133+
/// ```
134+
pub const fn aview2<A, const N: usize>(xs: &[[A; N]]) -> ArrayView2<'_, A> {
135+
let cols = N;
136+
let rows = xs.len();
137+
if size_of::<A>() == 0 {
138+
if let Some(n_elems) = rows.checked_mul(cols) {
139+
assert!(
140+
rows <= isize::MAX as usize
141+
&& cols <= isize::MAX as usize
142+
&& n_elems <= isize::MAX as usize,
143+
"Product of non-zero axis lengths must not overflow isize.",
144+
);
145+
} else {
146+
panic!("Overflow in number of elements.");
147+
}
148+
} else if N == 0 {
149+
assert!(
150+
rows <= isize::MAX as usize,
151+
"Product of non-zero axis lengths must not overflow isize.",
152+
);
153+
}
154+
// Safe because references are always non-null.
155+
let ptr = unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) };
156+
let dim = Ix2(rows, cols);
157+
let strides = if rows == 0 || cols == 0 {
158+
Ix2(0, 0)
159+
} else {
160+
Ix2(cols, 1)
161+
};
162+
ArrayBase {
163+
data: ViewRepr::new(),
164+
ptr,
165+
dim,
166+
strides,
167+
}
94168
}
95169

96170
/// Create a one-dimensional read-write array view with elements borrowing `xs`.

0 commit comments

Comments
 (0)