Skip to content

Commit edfbe81

Browse files
committed
Add .into_raw_vec_with_offset() and deprecate .into_raw_vec()
Provide a smoother transition by deprecating the old method and introducing a new one. Return Option<usize>, this makes the empty vector case stand out as a separate case that needs to be handled.
1 parent 6d04ebd commit edfbe81

File tree

5 files changed

+39
-11
lines changed

5 files changed

+39
-11
lines changed

examples/sort-axis.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ where D: Dimension
157157
});
158158
debug_assert_eq!(result.len(), moved_elements);
159159
// forget the old elements but not the allocation
160-
let mut old_storage = self.into_raw_vec().0;
160+
let mut old_storage = self.into_raw_vec_and_offset().0;
161161
old_storage.set_len(0);
162162

163163
// transfer ownership of the elements into the result

src/dimension/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ fn to_abs_slice(axis_len: usize, slice: Slice) -> (usize, usize, isize)
410410
}
411411

412412
/// This function computes the offset from the lowest address element to the
413-
/// logically first element. The result is always >= 0.
413+
/// logically first element.
414414
pub fn offset_from_low_addr_ptr_to_logical_ptr<D: Dimension>(dim: &D, strides: &D) -> usize
415415
{
416416
let offset = izip!(dim.slice(), strides.slice()).fold(0, |_offset, (&d, &s)| {

src/impl_owned_array.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ where D: Dimension
7777

7878
/// Return a vector of the elements in the array, in the way they are
7979
/// stored internally, and the index in the vector corresponding to the
80-
/// logically first element of the array (or `None` if the array is empty).
80+
/// logically first element of the array (or 0 if the array is empty).
8181
///
8282
/// If the array is in standard memory layout, the logical element order
8383
/// of the array (`.iter()` order) and of the returned vector will be the same.
@@ -92,7 +92,7 @@ where D: Dimension
9292
///
9393
/// let shape = arr.shape().to_owned();
9494
/// let strides = arr.strides().to_owned();
95-
/// let (v, offset) = arr.into_raw_vec();
95+
/// let (v, offset) = arr.into_raw_vec_and_offset();
9696
///
9797
/// assert_eq!(v, &[1., 2., 3., 4., 5., 6.]);
9898
/// assert_eq!(offset, Some(2));
@@ -124,7 +124,7 @@ where D: Dimension
124124
///
125125
/// let shape = arr.shape().to_owned();
126126
/// let strides = arr.strides().to_owned();
127-
/// let (v, offset) = arr.into_raw_vec();
127+
/// let (v, offset) = arr.into_raw_vec_and_offset();
128128
///
129129
/// assert_eq!(v, &[(), (), (), (), (), ()]);
130130
/// for row in 0..shape[0] {
@@ -138,11 +138,23 @@ where D: Dimension
138138
/// }
139139
/// }
140140
/// ```
141-
pub fn into_raw_vec(self) -> (Vec<A>, Option<usize>)
141+
pub fn into_raw_vec_and_offset(self) -> (Vec<A>, Option<usize>)
142142
{
143143
let offset = self.offset_from_alloc_to_logical_ptr();
144144
(self.data.into_vec(), offset)
145145
}
146+
147+
/// Return a vector of the elements in the array, in the way they are
148+
/// stored internally.
149+
///
150+
/// Depending on slicing and strides, the logically first element of the
151+
/// array can be located at an offset. Because of this, prefer to use
152+
/// `.into_raw_vec_and_offset()` instead.
153+
#[deprecated(note = "Use .into_raw_vec_and_offset() instead")]
154+
pub fn into_raw_vec(self) -> Vec<A>
155+
{
156+
self.into_raw_vec_and_offset().0
157+
}
146158
}
147159

148160
/// Methods specific to `Array2`.

tests/array-construct.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ fn test_from_shape_fn()
1919
fn test_dimension_zero()
2020
{
2121
let a: Array2<f32> = Array2::from(vec![[], [], []]);
22-
assert_eq!(vec![0.; 0], a.into_raw_vec().0);
22+
assert_eq!((vec![0.; 0], None), a.into_raw_vec_and_offset());
2323
let a: Array3<f32> = Array3::from(vec![[[]], [[]], [[]]]);
24-
assert_eq!(vec![0.; 0], a.into_raw_vec().0);
24+
assert_eq!((vec![0.; 0], None), a.into_raw_vec_and_offset());
2525
}
2626

2727
#[test]

tests/array.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,10 @@ fn array0_into_scalar()
11571157
// With this kind of setup, the `Array`'s pointer is not the same as the
11581158
// underlying `Vec`'s pointer.
11591159
let a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
1160-
assert_ne!(a.as_ptr(), a.into_raw_vec().0.as_ptr());
1160+
let a_ptr = a.as_ptr();
1161+
let (raw_vec, offset) = a.into_raw_vec_and_offset();
1162+
assert_ne!(a_ptr, raw_vec.as_ptr());
1163+
assert_eq!(offset, Some(2));
11611164
// `.into_scalar()` should still work correctly.
11621165
let a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
11631166
assert_eq!(a.into_scalar(), 6);
@@ -1173,7 +1176,10 @@ fn array_view0_into_scalar()
11731176
// With this kind of setup, the `Array`'s pointer is not the same as the
11741177
// underlying `Vec`'s pointer.
11751178
let a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
1176-
assert_ne!(a.as_ptr(), a.into_raw_vec().0.as_ptr());
1179+
let a_ptr = a.as_ptr();
1180+
let (raw_vec, offset) = a.into_raw_vec_and_offset();
1181+
assert_ne!(a_ptr, raw_vec.as_ptr());
1182+
assert_eq!(offset, Some(2));
11771183
// `.into_scalar()` should still work correctly.
11781184
let a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
11791185
assert_eq!(a.view().into_scalar(), &6);
@@ -1189,7 +1195,7 @@ fn array_view_mut0_into_scalar()
11891195
// With this kind of setup, the `Array`'s pointer is not the same as the
11901196
// underlying `Vec`'s pointer.
11911197
let a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
1192-
assert_ne!(a.as_ptr(), a.into_raw_vec().0.as_ptr());
1198+
assert_ne!(a.as_ptr(), a.into_raw_vec_and_offset().0.as_ptr());
11931199
// `.into_scalar()` should still work correctly.
11941200
let mut a: Array0<i32> = array![4, 5, 6, 7].index_axis_move(Axis(0), 2);
11951201
assert_eq!(a.view_mut().into_scalar(), &6);
@@ -1199,6 +1205,16 @@ fn array_view_mut0_into_scalar()
11991205
assert_eq!(a.view_mut().into_scalar(), &());
12001206
}
12011207

1208+
#[test]
1209+
fn array1_into_raw_vec()
1210+
{
1211+
let data = vec![4, 5, 6, 7];
1212+
let array = Array::from(data.clone());
1213+
let (raw_vec, offset) = array.into_raw_vec_and_offset();
1214+
assert_eq!(data, raw_vec);
1215+
assert_eq!(offset, Some(0));
1216+
}
1217+
12021218
#[test]
12031219
fn owned_array1()
12041220
{

0 commit comments

Comments
 (0)