@@ -2,6 +2,7 @@ use crate::alloc::{TryClone, try_realloc};
22use crate :: error:: OutOfMemory ;
33use core:: cmp:: Ordering ;
44use core:: marker:: PhantomData ;
5+ use core:: num:: NonZeroUsize ;
56use core:: {
67 fmt, mem,
78 ops:: { Deref , DerefMut , Index , IndexMut } ,
@@ -11,6 +12,38 @@ use std_alloc::alloc::Layout;
1112use std_alloc:: boxed:: Box ;
1213use std_alloc:: vec:: Vec as StdVec ;
1314
15+ /// Same as the [`std::vec!`] macro but returns an error on allocation failure.
16+ #[ macro_export]
17+ macro_rules! vec {
18+ ( $( $elem: expr ) ,* ) => { {
19+ let len = $crate:: private_len!( $( $elem ) ,* ) ;
20+ $crate:: alloc:: Vec :: with_capacity( len) . and_then( |mut v| {
21+ $( v. push( $elem) ?; ) *
22+ let _ = & mut v;
23+ Ok ( v)
24+ } )
25+ } } ;
26+
27+ ( $elem: expr; $len: expr ) => { {
28+ let len: usize = $len;
29+ if let Some ( len) = :: core:: num:: NonZeroUsize :: new( len) {
30+ let elem = $elem;
31+ $crate:: alloc:: Vec :: from_elem( elem, len)
32+ } else {
33+ Ok ( $crate:: alloc:: Vec :: new( ) )
34+ }
35+ } } ;
36+
37+ }
38+
39+ // Only for use by the `vec!` macro.
40+ #[ doc( hidden) ]
41+ #[ macro_export]
42+ macro_rules! private_len {
43+ ( ) => { 0 } ;
44+ ( $e: expr $( , $es: expr ) * ) => { 1 + $crate:: private_len!( $( $es ) ,* ) } ;
45+ }
46+
1447/// Like `std::vec::Vec` but all methods that allocate force handling allocation
1548/// failure.
1649#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
@@ -61,6 +94,25 @@ impl<T> Vec<T> {
6194 Ok ( v)
6295 }
6396
97+ // For use with the `vec!` macro.
98+ #[ doc( hidden) ]
99+ #[ inline]
100+ pub fn from_elem ( elem : T , len : NonZeroUsize ) -> Result < Self , OutOfMemory >
101+ where
102+ T : TryClone ,
103+ {
104+ let mut v = Self :: with_capacity ( len. get ( ) ) ?;
105+
106+ // Minimize calls to `TryClone` by always pushing `elem` itself as the
107+ // last element.
108+ for _ in 0 ..len. get ( ) - 1 {
109+ v. push ( elem. try_clone ( ) ?) ?;
110+ }
111+ v. push ( elem) ?;
112+
113+ Ok ( v)
114+ }
115+
64116 /// Same as [`std::vec::Vec::reserve`] but returns an error on allocation
65117 /// failure.
66118 pub fn reserve ( & mut self , additional : usize ) -> Result < ( ) , OutOfMemory > {
0 commit comments