Skip to main content

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