1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68


use std::collections::{TryReserveError};
use std::mem::ManuallyDrop;

#[cfg(test)]
mod testing;


/// Vec::with_capacity(capacity) panics/aborts when the capacity is too large.
/// This is a safer alternative which reports Error using try_reserve_exact.
///
/// ```
/// use with_capacity_safe::{vec_with_capacity_safe };
///
/// //let's pretend this is an arbitrary number read from a broken file
/// let number_from_file : usize = 100_000_000_000_000;
///
/// //try to create a 100TB Vec
/// let result : Result<Vec<u8>, _> = vec_with_capacity_safe(number_from_file);
///
/// assert!(result.is_err());
/// ```
pub fn vec_with_capacity_safe<T>(capacity : usize) -> Result<Vec<T>, TryReserveError>{
    let mut vec = Vec::new();
    vec.try_reserve_exact(capacity)?;
    Ok(vec)
}

/// A copy of Vec::into_raw_parts which is currently unstable.
/// The documentation below is also copy-pasted.
///
/// Decomposes a `Vec<T>` into its raw components.
///
/// Returns the raw pointer to the underlying data, the length of
/// the vector (in elements), and the allocated capacity of the
/// data (in elements). These are the same arguments in the same
/// order as the arguments to [`from_raw_parts`].
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Vec`. The only way to do
/// this is to convert the raw pointer, length, and capacity back
/// into a `Vec` with the [`from_raw_parts`] function, allowing
/// the destructor to perform the cleanup.
///
/// [`from_raw_parts`]: Vec::from_raw_parts
///
/// # Examples
///
/// ```
/// use with_capacity_safe::vec_into_raw_parts;
/// let v: Vec<i32> = vec![-1, 0, 1];
///
/// let (ptr, len, cap) = vec_into_raw_parts(v);
///
/// let rebuilt = unsafe {
///     // We can now make changes to the components, such as
///     // transmuting the raw pointer to a compatible type.
///     let ptr = ptr as *mut u32;
///
///     Vec::from_raw_parts(ptr, len, cap)
/// };
/// assert_eq!(rebuilt, [4294967295, 0, 1]);
/// ```
pub fn vec_into_raw_parts<T>(vec : Vec<T>) -> (*mut T, usize, usize) {
    let mut me = ManuallyDrop::new(vec);
    (me.as_mut_ptr(), me.len(), me.capacity())
}