smallvec_wrapper/
lib.rs

1//! Macro and common structs to play with [`smallvec`].
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(docsrs, allow(unused_attributes))]
5#![deny(missing_docs)]
6
7pub use either;
8use either::Either;
9
10#[cfg(not(feature = "std"))]
11extern crate alloc as std;
12
13#[doc(hidden)]
14pub mod __private {
15  pub use either;
16  pub use paste;
17  pub use smallvec;
18
19  pub use std::boxed::Box;
20  pub use std::{vec, vec::Vec};
21}
22
23/// Wraps a `SmallVec` with a newtype.
24#[macro_export]
25macro_rules! smallvec_wrapper {
26  (
27    $(#[$meta:meta])*
28    $vis:vis $name:ident $(<$($generic:tt),+>)? ([$inner:ty; $inlined: expr]);
29  ) => {
30    $crate::__private::paste::paste! {
31      $(#[$meta])*
32      $vis struct $name $(< $($generic),+ >)? ($crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>);
33
34      impl $(< $($generic),+ >)? ::core::default::Default for $name $(< $($generic),+ >)? {
35        fn default() -> Self {
36          Self::new()
37        }
38      }
39
40      impl $(< $($generic),+ >)? $name $(< $($generic),+ >)? {
41        /// Creates a new instance.
42        #[inline]
43        pub const fn new() -> Self {
44          Self($crate::__private::smallvec::SmallVec::new_const())
45        }
46
47        /// Constructs a new instance on the stack from an array without copying elements.
48        #[inline]
49        pub const fn from_buf(value: [$inner; { $inlined }]) -> Self {
50          Self($crate::__private::smallvec::SmallVec::from_const(value))
51        }
52
53        /// Constructs a new instance on the stack from an array without copying elements. Also sets the length, which must be less or equal to the size of buf.
54        #[inline]
55        pub fn from_buf_and_len(value: [$inner; { $inlined }], len: usize) -> Self {
56          Self($crate::__private::smallvec::SmallVec::from_buf_and_len(value, len))
57        }
58
59        /// Constructs a new instance on the stack from an array without copying elements. Also sets the length. The user is responsible for ensuring that `len <= N`.
60        ///
61        /// # Safety
62        /// - The user is responsible for ensuring that `len <= N`.
63        #[inline]
64        pub const unsafe fn from_const_with_len_unchecked(value: [$inner; { $inlined }], len: usize) -> Self {
65          Self($crate::__private::smallvec::SmallVec::from_const_with_len_unchecked(value, len))
66        }
67
68        /// Creates a new instance of `ApplyBatchResponse` with the given capacity.
69        pub fn with_capacity(capacity: usize) -> Self {
70          Self($crate::__private::smallvec::SmallVec::with_capacity(capacity))
71        }
72
73        /// Convert self into an `Either::Left` if possible. Otherwise return `Either::Right`.
74        ///
75        /// This method returns `Either::Left` if the self is on the stack,
76        /// or if the `Either::Right` is too long (and all the elements were spilled to the heap).
77        pub fn into_either(self) -> $crate::__private::either::Either<[$inner; { $inlined }], $crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>> {
78          match self.0.into_inner() {
79            ::core::result::Result::Ok(x) => $crate::__private::either::Either::Left(x),
80            ::core::result::Result::Err(x) => $crate::__private::either::Either::Right(x),
81          }
82        }
83
84        /// Convert [`Either`] into self.
85        #[inline]
86        pub fn from_either(either: $crate::__private::either::Either<[$inner; { $inlined }], $crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>>) -> Self {
87          match either {
88            $crate::__private::either::Either::Left(x) => Self($crate::__private::smallvec::SmallVec::from(x)),
89            $crate::__private::either::Either::Right(x) => Self(x),
90          }
91        }
92
93        #[doc = "Convert the `" $name "` into an `A` if possible. Otherwise return `Err(Self)`."]
94        ///
95        #[doc = "This method returns `Err(Self)` if the `" $name "` is too short (and the `A` contains uninitialized elements),"]
96        #[doc = "or if the `" $name "` is too long (and all the elements were spilled to the heap)."]
97        pub fn into_inner(self) -> $crate::__private::either::Either<[$inner; { $inlined }], $crate::__private::Vec<$inner>> {
98          match self.0.into_inner() {
99            ::core::result::Result::Ok(x) => $crate::__private::either::Either::Left(x),
100            ::core::result::Result::Err(x) => $crate::__private::either::Either::Right(x.into_vec()),
101          }
102        }
103
104        /// Converts a `SmallVec` into a `Box<[T]>` without reallocating if the `SmallVec` has already spilled
105        #[doc = "Converts a `" $name "` into a `Box<[T]>` without reallocating if the `" $name "` has already spilled"]
106        /// onto the heap.
107        ///
108        /// Note that this will drop any excess capacity.
109        pub fn into_boxed_slice(self) -> $crate::__private::Box<[$inner]> {
110          self.0.into_boxed_slice()
111        }
112
113        #[doc = "Converts a `" $name "` into a `Vec` without reallocating if the `" $name "` has already spilled"]
114        /// onto the heap.
115        pub fn into_vec(self) -> $crate::__private::Vec<$inner> {
116          self.0.into_vec()
117        }
118
119        #[doc = "Construct a new `" $name "` from a `Vec<A::Item>`."]
120        ///
121        /// Elements will be copied to the inline buffer if `vec.capacity() <= Self::inline_capacity()`.
122        #[inline]
123        pub fn from_vec(vec: $crate::__private::Vec<$inner>) -> Self {
124          Self($crate::__private::smallvec::SmallVec::from_vec(vec))
125        }
126      }
127
128      impl $(< $($generic),+ >)? ::core::convert::From<$inner> for $name $(< $($generic),+ >)? {
129        fn from(value: $inner) -> Self {
130          Self($crate::__private::smallvec::smallvec![value])
131        }
132      }
133
134      impl $(< $($generic),+ >)? ::core::convert::From<::std::vec::Vec<$inner>> for $name $(< $($generic),+ >)? {
135        fn from(values: ::std::vec::Vec<$inner>) -> Self {
136          Self(::core::convert::Into::into(values))
137        }
138      }
139
140      impl $(< $($generic),+ >)? ::core::convert::From<&[$inner]> for $name $(< $($generic),+ >)?
141      where
142        $inner: ::core::clone::Clone,
143      {
144        fn from(values: &[$inner]) -> Self {
145          Self(::core::convert::Into::into(values))
146        }
147      }
148
149      impl $(< $($generic),+ >)? ::core::convert::From<::core::option::Option<$inner>> for $name $(< $($generic),+ >)? {
150        fn from(value: ::core::option::Option<$inner>) -> Self {
151          match value {
152            ::core::option::Option::Some(value) => Self($crate::__private::smallvec::smallvec![value]),
153            ::core::option::Option::None => Self($crate::__private::smallvec::SmallVec::new()),
154          }
155        }
156      }
157
158      impl $(< $($generic),+ >)? ::core::convert::From<[$inner; { $inlined }]> for $name $(< $($generic),+ >)? {
159        fn from(value: [$inner; { $inlined }]) -> Self {
160          Self(value.into())
161        }
162      }
163
164      impl $(< $($generic),+ >)? ::core::convert::From<$crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>> for $name $(< $($generic),+ >)? {
165        fn from(value: $crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>) -> Self {
166          Self(value)
167        }
168      }
169
170      impl $(< $($generic),+ >)? ::core::ops::Deref for $name $(< $($generic),+ >)? {
171        type Target = $crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>;
172
173        fn deref(&self) -> &Self::Target {
174          &self.0
175        }
176      }
177
178      impl $(< $($generic),+ >)? ::core::ops::DerefMut for $name $(< $($generic),+ >)? {
179        fn deref_mut(&mut self) -> &mut Self::Target {
180          &mut self.0
181        }
182      }
183
184      impl $(< $($generic),+ >)? ::core::borrow::Borrow<[$inner]> for $name $(< $($generic),+ >)? {
185        fn borrow(&self) -> &[$inner] {
186          &self.0
187        }
188      }
189
190      impl $(< $($generic),+ >)? ::core::borrow::BorrowMut<[$inner]> for $name $(< $($generic),+ >)? {
191        fn borrow_mut(&mut self) -> &mut [$inner] {
192          &mut self.0
193        }
194      }
195
196      impl $(< $($generic),+ >)? ::core::convert::AsRef<$crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>> for $name $(< $($generic),+ >)? {
197        fn as_ref(&self) -> &$crate::__private::smallvec::SmallVec<[$inner; { $inlined }]> {
198          &self.0
199        }
200      }
201
202      impl $(< $($generic),+ >)? ::core::convert::AsMut<$crate::__private::smallvec::SmallVec<[$inner; { $inlined }]>> for $name $(< $($generic),+ >)? {
203        fn as_mut(&mut self) -> &mut $crate::__private::smallvec::SmallVec<[$inner; { $inlined }]> {
204          &mut self.0
205        }
206      }
207
208      impl $(< $($generic),+ >)? ::core::convert::AsRef<[$inner]> for $name $(< $($generic),+ >)? {
209        fn as_ref(&self) -> &[$inner] {
210          &self.0
211        }
212      }
213
214      impl $(< $($generic),+ >)? ::core::convert::AsMut<[$inner]> for $name $(< $($generic),+ >)? {
215        fn as_mut(&mut self) -> &mut [$inner] {
216          &mut self.0
217        }
218      }
219
220      impl $(< $($generic),+ >)? ::core::iter::FromIterator<$inner> for $name $(< $($generic),+ >)? {
221        fn from_iter<__T: ::core::iter::IntoIterator<Item = $inner>>(iter: __T) -> Self {
222          Self(iter.into_iter().collect())
223        }
224      }
225
226      impl $(< $($generic),+ >)? ::core::iter::IntoIterator for $name $(< $($generic),+ >)? {
227        type Item = $inner;
228        type IntoIter = $crate::__private::smallvec::IntoIter<[$inner; { $inlined }]>;
229
230        fn into_iter(self) -> Self::IntoIter {
231          self.0.into_iter()
232        }
233      }
234
235      impl<'a, $( $($generic),+ )?> ::core::iter::IntoIterator for &'a $name $(< $($generic),+ >)? {
236        type Item = &'a $inner;
237        type IntoIter = ::core::slice::Iter<'a, $inner>;
238
239        fn into_iter(self) -> Self::IntoIter {
240          (&self.0).into_iter()
241        }
242      }
243
244      impl<'a, $( $($generic),+ )?> ::core::iter::IntoIterator for &'a mut $name $(< $($generic),+ >)? {
245        type Item = &'a mut $inner;
246        type IntoIter = ::core::slice::IterMut<'a, $inner>;
247
248        fn into_iter(self) -> Self::IntoIter {
249          (&mut self.0).into_iter()
250        }
251      }
252
253      impl $(< $($generic),+ >)? ::core::iter::Extend<$inner> for $name $(< $($generic),+ >)? {
254        #[inline]
255        fn extend<I: ::core::iter::IntoIterator<Item = $inner>>(&mut self, iter: I) {
256          self.0.extend(iter)
257        }
258      }
259    }
260  };
261}
262
263impl<T> From<Either<T, ::smallvec::SmallVec<[T; 1]>>> for OneOrMore<T> {
264  #[inline]
265  fn from(either: Either<T, ::smallvec::SmallVec<[T; 1]>>) -> Self {
266    match either {
267      Either::Left(t) => OneOrMore::from(t),
268      Either::Right(vec) => OneOrMore::from(vec),
269    }
270  }
271}
272
273impl<T> From<Either<Option<T>, ::smallvec::SmallVec<[T; 1]>>> for OneOrMore<T> {
274  #[inline]
275  fn from(either: Either<Option<T>, ::smallvec::SmallVec<[T; 1]>>) -> Self {
276    match either {
277      Either::Left(t) => OneOrMore::from(t),
278      Either::Right(vec) => OneOrMore::from(vec),
279    }
280  }
281}
282
283smallvec_wrapper!(
284  /// A tiny vec which can inline 1 element on stack.
285  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
286  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
287  #[cfg_attr(feature = "serde", serde(transparent))]
288  #[cfg_attr(
289    feature = "rkyv",
290    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
291  )]
292  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
293  pub OneOrMore<T>([T; 1]);
294);
295
296smallvec_wrapper!(
297  /// A tiny vec which can inline 2 elements on stack.
298  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
299  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
300  #[cfg_attr(feature = "serde", serde(transparent))]
301  #[cfg_attr(
302    feature = "rkyv",
303    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
304  )]
305  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
306  pub TinyVec<T>([T; 2]);
307);
308
309smallvec_wrapper!(
310  /// A vec which can inline 3 elements on stack.
311  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
312  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
313  #[cfg_attr(feature = "serde", serde(transparent))]
314  #[cfg_attr(
315    feature = "rkyv",
316    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
317  )]
318  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
319  pub TriVec<T>([T; 3]);
320);
321
322smallvec_wrapper!(
323  /// A small vec which can inline 4 elements on stack.
324  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
325  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
326  #[cfg_attr(feature = "serde", serde(transparent))]
327  #[cfg_attr(
328    feature = "rkyv",
329    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
330  )]
331  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
332  pub SmallVec<T>([T; 4]);
333);
334
335smallvec_wrapper!(
336  /// A medium vec which can inline 8 elements on stack.
337  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
338  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
339  #[cfg_attr(feature = "serde", serde(transparent))]
340  #[cfg_attr(
341    feature = "rkyv",
342    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
343  )]
344  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
345  pub MediumVec<T>([T; 8]);
346);
347
348smallvec_wrapper!(
349  /// A big vec which can inline 16 elements on stack.
350  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
351  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
352  #[cfg_attr(feature = "serde", serde(transparent))]
353  #[cfg_attr(
354    feature = "rkyv",
355    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
356  )]
357  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
358  pub LargeVec<T>([T; 16]);
359);
360
361smallvec_wrapper!(
362  /// A xlarge vec which can inline 32 elements on stack.
363  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
364  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
365  #[cfg_attr(feature = "serde", serde(transparent))]
366  #[cfg_attr(
367    feature = "rkyv",
368    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
369  )]
370  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
371  pub XLargeVec<T>([T; 32]);
372);
373
374smallvec_wrapper!(
375  /// A xxlarge vec which can inline 64 elements on stack.
376  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
377  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
378  #[cfg_attr(feature = "serde", serde(transparent))]
379  #[cfg_attr(
380    feature = "rkyv",
381    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
382  )]
383  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
384  pub XXLargeVec<T>([T; 64]);
385);
386
387smallvec_wrapper!(
388  /// A xxxlarge vec which can inline 128 elements on stack.
389  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
390  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
391  #[cfg_attr(feature = "serde", serde(transparent))]
392  #[cfg_attr(
393    feature = "rkyv",
394    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
395  )]
396  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
397  pub XXXLargeVec<T>([T; 128]);
398);