72
72
//!
73
73
//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
74
74
//!
75
- //! This feature exposes the function [`SmallVec::new_const`] which is a `const fn` so the `SmallVec` may be used from a const context.
75
+ //! This feature exposes the functions [`SmallVec::new_const`] and [`SmallVec::from_const`] which enables the `SmallVec` to be initialized from a const context.
76
76
//! For details, see the
77
77
//! [Rust Reference](https://doc.rust-lang.org/reference/const_eval.html#const-functions).
78
78
//!
79
79
//! Tracking issue: [rust-lang/rust#57563](https://github.com/rust-lang/rust/issues/57563)
80
80
81
81
#![ no_std]
82
+ #![ cfg_attr( docsrs, feature( doc_cfg) ) ]
82
83
#![ cfg_attr( feature = "specialization" , allow( incomplete_features) ) ]
83
84
#![ cfg_attr( feature = "specialization" , feature( specialization) ) ]
84
85
#![ cfg_attr( feature = "may_dangle" , feature( dropck_eyepatch) ) ]
@@ -181,6 +182,53 @@ macro_rules! smallvec {
181
182
} ) ;
182
183
}
183
184
185
+
186
+ /// Creates an inline [`SmallVec`] containing the arguments. This macro is enabled by the feature `const_new`.
187
+ ///
188
+ /// `smallvec_inline!` allows `SmallVec`s to be defined with the same syntax as array expressions in `const` contexts.
189
+ /// The inline storage `A` will always be an array of the size specified by the arguments.
190
+ /// There are two forms of this macro:
191
+ ///
192
+ /// - Create a [`SmallVec`] containing a given list of elements:
193
+ ///
194
+ /// ```
195
+ /// # #[macro_use] extern crate smallvec;
196
+ /// # use smallvec::SmallVec;
197
+ /// # fn main() {
198
+ /// const V: SmallVec<[i32; 3]> = smallvec_inline![1, 2, 3];
199
+ /// assert_eq!(V[0], 1);
200
+ /// assert_eq!(V[1], 2);
201
+ /// assert_eq!(V[2], 3);
202
+ /// # }
203
+ /// ```
204
+ ///
205
+ /// - Create a [`SmallVec`] from a given element and size:
206
+ ///
207
+ /// ```
208
+ /// # #[macro_use] extern crate smallvec;
209
+ /// # use smallvec::SmallVec;
210
+ /// # fn main() {
211
+ /// const V: SmallVec<[i32; 3]> = smallvec_inline![1; 3];
212
+ /// assert_eq!(V, SmallVec::from_buf([1, 1, 1]));
213
+ /// # }
214
+ /// ```
215
+ ///
216
+ /// Note that the behavior mimics that of array expressions, in contrast to [`smallvec`].
217
+ #[ cfg( feature = "const_new" ) ]
218
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_new" ) ) ) ]
219
+ #[ macro_export]
220
+ macro_rules! smallvec_inline {
221
+ // count helper: transform any expression into 1
222
+ ( @one $x: expr) => ( 1usize ) ;
223
+ ( $elem: expr; $n: expr) => ( {
224
+ $crate:: SmallVec :: <[ _; $n] >:: from_const( [ $elem; $n] )
225
+ } ) ;
226
+ ( $( $x: expr) ,+ $( , ) ?) => ( {
227
+ const N : usize = 0usize $( + $crate:: smallvec_inline!( @one $x) ) * ;
228
+ $crate:: SmallVec :: <[ _; N ] >:: from_const( [ $( $x, ) * ] )
229
+ } ) ;
230
+ }
231
+
184
232
/// `panic!()` in debug builds, optimization hint in release.
185
233
#[ cfg( not( feature = "union" ) ) ]
186
234
macro_rules! debug_unreachable {
@@ -366,6 +414,7 @@ union SmallVecData<A: Array> {
366
414
367
415
#[ cfg( all( feature = "union" , feature = "const_new" ) ) ]
368
416
impl < A : Array > SmallVecData < A > {
417
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_new" ) ) ) ]
369
418
#[ inline]
370
419
const fn from_const ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
371
420
SmallVecData {
@@ -416,6 +465,7 @@ enum SmallVecData<A: Array> {
416
465
417
466
#[ cfg( all( not( feature = "union" ) , feature = "const_new" ) ) ]
418
467
impl < A : Array > SmallVecData < A > {
468
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_new" ) ) ) ]
419
469
#[ inline]
420
470
const fn from_const ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
421
471
SmallVecData :: Inline ( inline)
@@ -1360,7 +1410,7 @@ impl<A: Array> SmallVec<A> {
1360
1410
1361
1411
#[ cfg( feature = "const_new" ) ]
1362
1412
impl < A : Array > SmallVec < A > {
1363
- /// Construct an empty vector.
1413
+ /// Construct an empty vector. This is currently gated behind the feature `const_new`.
1364
1414
///
1365
1415
/// # Safety
1366
1416
/// No size validation is attempted for this function.
@@ -1369,6 +1419,7 @@ impl<A: Array> SmallVec<A> {
1369
1419
///
1370
1420
/// [`Array`]: crate::Array
1371
1421
/// [`new`]: crate::SmallVec::new
1422
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_new" ) ) ) ]
1372
1423
#[ inline]
1373
1424
pub const unsafe fn new_const ( ) -> SmallVec < A > {
1374
1425
SmallVec {
@@ -1536,6 +1587,7 @@ impl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {
1536
1587
}
1537
1588
1538
1589
#[ cfg( feature = "write" ) ]
1590
+ #[ cfg_attr( docsrs, doc( cfg( feature = "write" ) ) ) ]
1539
1591
impl < A : Array < Item = u8 > > io:: Write for SmallVec < A > {
1540
1592
#[ inline]
1541
1593
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
@@ -1556,6 +1608,7 @@ impl<A: Array<Item = u8>> io::Write for SmallVec<A> {
1556
1608
}
1557
1609
1558
1610
#[ cfg( feature = "serde" ) ]
1611
+ #[ cfg_attr( docsrs, doc( cfg( feature = "serde" ) ) ) ]
1559
1612
impl < A : Array > Serialize for SmallVec < A >
1560
1613
where
1561
1614
A :: Item : Serialize ,
@@ -1570,6 +1623,7 @@ where
1570
1623
}
1571
1624
1572
1625
#[ cfg( feature = "serde" ) ]
1626
+ #[ cfg_attr( docsrs, doc( cfg( feature = "serde" ) ) ) ]
1573
1627
impl < ' de , A : Array > Deserialize < ' de > for SmallVec < A >
1574
1628
where
1575
1629
A :: Item : Deserialize < ' de > ,
@@ -1999,15 +2053,30 @@ impl<'a> Drop for SetLenOnDrop<'a> {
1999
2053
}
2000
2054
}
2001
2055
2002
- #[ cfg( feature = "const_generics" ) ]
2056
+ #[ cfg( feature = "const_new" ) ]
2057
+ impl < T , const N : usize > SmallVec < [ T ; N ] > {
2058
+ /// The array passed as an argument is moved to be an inline version of `SmallVec`.
2059
+ /// This is a `const` version of [`SmallVec::from_buf`] that is enabled by the feature `const_new`, with the limitation that it only works for arrays.
2060
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_new" ) ) ) ]
2061
+ #[ inline]
2062
+ pub const fn from_const ( items : [ T ; N ] ) -> SmallVec < [ T ; N ] > {
2063
+ SmallVec {
2064
+ capacity : N ,
2065
+ data : SmallVecData :: from_const ( MaybeUninit :: new ( items) ) ,
2066
+ }
2067
+ }
2068
+ }
2069
+
2070
+ #[ cfg( all( feature = "const_generics" , not( doc) ) ) ]
2071
+ #[ cfg_attr( docsrs, doc( cfg( feature = "const_generics" ) ) ) ]
2003
2072
unsafe impl < T , const N : usize > Array for [ T ; N ] {
2004
2073
type Item = T ;
2005
2074
fn size ( ) -> usize {
2006
2075
N
2007
2076
}
2008
2077
}
2009
2078
2010
- #[ cfg( not( feature = "const_generics" ) ) ]
2079
+ #[ cfg( any ( not( feature = "const_generics" ) , doc ) ) ]
2011
2080
macro_rules! impl_array(
2012
2081
( $( $size: expr) ,+) => {
2013
2082
$(
@@ -2019,7 +2088,7 @@ macro_rules! impl_array(
2019
2088
}
2020
2089
) ;
2021
2090
2022
- #[ cfg( not( feature = "const_generics" ) ) ]
2091
+ #[ cfg( any ( not( feature = "const_generics" ) , doc ) ) ]
2023
2092
impl_array ! (
2024
2093
0 , 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 ,
2025
2094
26 , 27 , 28 , 29 , 30 , 31 , 32 , 36 , 0x40 , 0x60 , 0x80 , 0x100 , 0x200 , 0x400 , 0x600 , 0x800 , 0x1000 ,
0 commit comments