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  };
264}
265
266impl<T> From<Either<T, ::smallvec::SmallVec<[T; 1]>>> for OneOrMore<T> {
267  #[inline]
268  fn from(either: Either<T, ::smallvec::SmallVec<[T; 1]>>) -> Self {
269    match either {
270      Either::Left(t) => OneOrMore::from(t),
271      Either::Right(vec) => OneOrMore::from(vec),
272    }
273  }
274}
275
276impl<T> From<Either<Option<T>, ::smallvec::SmallVec<[T; 1]>>> for OneOrMore<T> {
277  #[inline]
278  fn from(either: Either<Option<T>, ::smallvec::SmallVec<[T; 1]>>) -> Self {
279    match either {
280      Either::Left(t) => OneOrMore::from(t),
281      Either::Right(vec) => OneOrMore::from(vec),
282    }
283  }
284}
285
286smallvec_wrapper!(
287  /// A tiny vec which can inline 1 element on stack.
288  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
289  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
290  #[cfg_attr(feature = "serde", serde(transparent))]
291  #[cfg_attr(
292    feature = "rkyv",
293    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
294  )]
295  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
296  pub OneOrMore<T>([T; 1]);
297);
298
299smallvec_wrapper!(
300  /// A tiny vec which can inline 2 elements on stack.
301  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
302  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
303  #[cfg_attr(feature = "serde", serde(transparent))]
304  #[cfg_attr(
305    feature = "rkyv",
306    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
307  )]
308  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
309  pub TinyVec<T>([T; 2]);
310);
311
312smallvec_wrapper!(
313  /// A vec which can inline 3 elements on stack.
314  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
315  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
316  #[cfg_attr(feature = "serde", serde(transparent))]
317  #[cfg_attr(
318    feature = "rkyv",
319    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
320  )]
321  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
322  pub TriVec<T>([T; 3]);
323);
324
325smallvec_wrapper!(
326  /// A small vec which can inline 4 elements on stack.
327  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
328  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
329  #[cfg_attr(feature = "serde", serde(transparent))]
330  #[cfg_attr(
331    feature = "rkyv",
332    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
333  )]
334  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
335  pub SmallVec<T>([T; 4]);
336);
337
338smallvec_wrapper!(
339  /// A medium vec which can inline 8 elements on stack.
340  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
341  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
342  #[cfg_attr(feature = "serde", serde(transparent))]
343  #[cfg_attr(
344    feature = "rkyv",
345    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
346  )]
347  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
348  pub MediumVec<T>([T; 8]);
349);
350
351smallvec_wrapper!(
352  /// A big vec which can inline 16 elements on stack.
353  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
354  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
355  #[cfg_attr(feature = "serde", serde(transparent))]
356  #[cfg_attr(
357    feature = "rkyv",
358    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
359  )]
360  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
361  pub LargeVec<T>([T; 16]);
362);
363
364smallvec_wrapper!(
365  /// A xlarge vec which can inline 32 elements on stack.
366  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
367  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
368  #[cfg_attr(feature = "serde", serde(transparent))]
369  #[cfg_attr(
370    feature = "rkyv",
371    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
372  )]
373  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
374  pub XLargeVec<T>([T; 32]);
375);
376
377smallvec_wrapper!(
378  /// A xxlarge vec which can inline 64 elements on stack.
379  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
380  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
381  #[cfg_attr(feature = "serde", serde(transparent))]
382  #[cfg_attr(
383    feature = "rkyv",
384    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
385  )]
386  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
387  pub XXLargeVec<T>([T; 64]);
388);
389
390smallvec_wrapper!(
391  /// A xxxlarge vec which can inline 128 elements on stack.
392  #[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
393  #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
394  #[cfg_attr(feature = "serde", serde(transparent))]
395  #[cfg_attr(
396    feature = "rkyv",
397    derive(::rkyv::Serialize, ::rkyv::Deserialize, ::rkyv::Archive)
398  )]
399  #[cfg_attr(feature = "rkyv", rkyv(compare(PartialEq)))]
400  pub XXXLargeVec<T>([T; 128]);
401);