@@ -1254,7 +1254,37 @@ impl<T, A: Allocator> Vec<T, A> {
1254
1254
#[ inline]
1255
1255
#[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
1256
1256
pub fn as_slice ( & self ) -> & [ T ] {
1257
- self
1257
+ self . as_slice_const ( )
1258
+ }
1259
+
1260
+ /// Extracts a slice containing the entire vector.
1261
+ ///
1262
+ /// # Examples
1263
+ ///
1264
+ /// ```
1265
+ /// # use std::borrow::Cow;
1266
+ /// // `Deref`, `AsRef`, and `as_slice` are not available in `const` contexts, so this doesn't otherwise work.
1267
+ /// const fn cow_slice<'c, 's>(c: &Cow<'s, [u8]>) -> &'c [u8]
1268
+ /// where 's: 'c {
1269
+ /// match c {
1270
+ /// Cow::Borrowed(s) => s,
1271
+ /// Cow::Owned(s) => s.as_slice_const(),
1272
+ /// }
1273
+ /// }
1274
+ ///
1275
+ /// const VEC: Cow<'static, [u8]> = Cow::Owned(Vec::new());
1276
+ /// const SLICE: Cow<'static, [u8]> = Cow::Borrowed(b"foo");
1277
+ ///
1278
+ /// const SLICED_VEC: &'static [u8] = cow_slice(&VEC);
1279
+ /// const SLICED_SLICE: &'static [u8] = cow_slice(&SLICE);
1280
+ ///
1281
+ /// assert_eq!(SLICED_VEC, b"");
1282
+ /// assert_eq!(SLICED_SLICE, b"foo");
1283
+ /// ```
1284
+ #[ inline]
1285
+ #[ unstable( feature = "const_vec_string_slice" , issue = "none" ) ]
1286
+ pub const fn as_slice_const ( & self ) -> & [ T ] {
1287
+ unsafe { slice:: from_raw_parts ( self . as_ptr_const ( ) , self . len ) }
1258
1288
}
1259
1289
1260
1290
/// Extracts a mutable slice of the entire vector.
@@ -1271,7 +1301,7 @@ impl<T, A: Allocator> Vec<T, A> {
1271
1301
#[ inline]
1272
1302
#[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
1273
1303
pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
1274
- self
1304
+ unsafe { slice :: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
1275
1305
}
1276
1306
1277
1307
/// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -1334,6 +1364,68 @@ impl<T, A: Allocator> Vec<T, A> {
1334
1364
self . buf . ptr ( )
1335
1365
}
1336
1366
1367
+ /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
1368
+ /// valid for zero sized reads if the vector didn't allocate.
1369
+ ///
1370
+ /// This is a `const` version of [`as_ptr`].
1371
+ ///
1372
+ /// The caller must ensure that the vector outlives the pointer this
1373
+ /// function returns, or else it will end up pointing to garbage.
1374
+ /// Modifying the vector may cause its buffer to be reallocated,
1375
+ /// which would also make any pointers to it invalid.
1376
+ ///
1377
+ /// The caller must also ensure that the memory the pointer (non-transitively) points to
1378
+ /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
1379
+ /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
1380
+ ///
1381
+ /// This method guarantees that for the purpose of the aliasing model, this method
1382
+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
1383
+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1384
+ /// Note that calling other methods that materialize mutable references to the slice,
1385
+ /// or mutable references to specific elements you are planning on accessing through this pointer,
1386
+ /// as well as writing to those elements, may still invalidate this pointer.
1387
+ /// See the second example below for how this guarantee can be used.
1388
+ ///
1389
+ ///
1390
+ /// # Examples
1391
+ ///
1392
+ /// ```
1393
+ /// let x = vec![1, 2, 4];
1394
+ /// let x_ptr = x.as_ptr_const();
1395
+ ///
1396
+ /// unsafe {
1397
+ /// for i in 0..x.len() {
1398
+ /// assert_eq!(*x_ptr.add(i), 1 << i);
1399
+ /// }
1400
+ /// }
1401
+ /// ```
1402
+ ///
1403
+ /// Due to the aliasing guarantee, the following code is legal:
1404
+ ///
1405
+ /// ```rust
1406
+ /// unsafe {
1407
+ /// let mut v = vec![0, 1, 2];
1408
+ /// let ptr1 = v.as_ptr_const();
1409
+ /// let _ = ptr1.read();
1410
+ /// let ptr2 = v.as_mut_ptr().offset(2);
1411
+ /// ptr2.write(2);
1412
+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`
1413
+ /// // because it mutated a different element:
1414
+ /// let _ = ptr1.read();
1415
+ /// }
1416
+ /// ```
1417
+ ///
1418
+ /// [`as_mut_ptr`]: Vec::as_mut_ptr
1419
+ /// [`as_ptr_const`]: Vec::as_ptr
1420
+ #[ rustc_never_returns_null_ptr]
1421
+ #[ unstable( feature = "const_vec_string_slice" , issue = "none" ) ]
1422
+ #[ inline]
1423
+ pub const fn as_ptr_const ( & self ) -> * const T {
1424
+ // We shadow the slice method of the same name to avoid going through
1425
+ // `deref`, which creates an intermediate reference.
1426
+ self . buf . ptr_const ( )
1427
+ }
1428
+
1337
1429
/// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
1338
1430
/// raw pointer valid for zero sized reads if the vector didn't allocate.
1339
1431
///
@@ -2828,15 +2920,15 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
2828
2920
2829
2921
#[ inline]
2830
2922
fn deref ( & self ) -> & [ T ] {
2831
- unsafe { slice :: from_raw_parts ( self . as_ptr ( ) , self . len ) }
2923
+ self . as_slice ( )
2832
2924
}
2833
2925
}
2834
2926
2835
2927
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2836
2928
impl < T , A : Allocator > ops:: DerefMut for Vec < T , A > {
2837
2929
#[ inline]
2838
2930
fn deref_mut ( & mut self ) -> & mut [ T ] {
2839
- unsafe { slice :: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
2931
+ self . as_mut_slice ( )
2840
2932
}
2841
2933
}
2842
2934
0 commit comments