Skip to main content

columnar/
boxed.rs

1//! Support for `Box<T>` where `T: Columnar`.
2//!
3//! The implementation defers to `T`'s implementation to store data. It reveals
4//! the same reference type as `T`, wrapped in [`Boxed`].
5//!
6//! We need this wrapper to distinguish which [`Push`] implementation to use, otherwise
7//! the implementations would conflict.
8use alloc::boxed::Box;
9use alloc::{string::String, vec::Vec};
10
11use crate::{AsBytes, Borrow, Clear, Columnar, Container, FromBytes, Index, IndexMut, Len, Push, Ref};
12
13impl<T: Columnar> Columnar for Box<T> {
14    type Container = Boxed<T::Container>;
15    #[inline(always)] fn copy_from<'a>(&mut self, other: Ref<'a, Self>) { self.as_mut().copy_from(other.0); }
16    #[inline(always)] fn into_owned<'a>(other: Ref<'a, Self>) -> Self { T::into_owned(other.0).into() }
17}
18
19/// A newtype wrapper around `T` that implements `Deref` and `DerefMut`.
20#[derive(Copy, Clone, Default)]
21pub struct Boxed<T>(pub T);
22
23impl<T> core::ops::Deref for Boxed<T> {
24    type Target = T;
25    #[inline(always)] fn deref(&self) -> &T { &self.0 }
26}
27impl<T> core::ops::DerefMut for Boxed<T> {
28    #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.0 }
29}
30impl<C: Borrow> Borrow for Boxed<C> {
31    type Ref<'a> = Boxed<C::Ref<'a>>;
32    type Borrowed<'a> = Boxed<C::Borrowed<'a>>;
33    #[inline(always)] fn borrow<'a>(&'a self) -> Self::Borrowed<'a> { Boxed(self.0.borrow()) }
34    #[inline(always)] fn reborrow<'b, 'a: 'b>(item: Self::Borrowed<'a>) -> Self::Borrowed<'b> where Self: 'a { Boxed(C::reborrow(item.0)) }
35    #[inline(always)] fn reborrow_ref<'b, 'a: 'b>(item: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { Boxed(C::reborrow_ref(item.0)) }
36}
37impl<C: Container> Container for Boxed<C> {
38    #[inline(always)] fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) { self.0.extend_from_self(other.0, range) }
39    #[inline(always)] fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { self.0.reserve_for(selves.map(|x| x.0)) }
40}
41impl<C: Len> Len for Boxed<C> {
42    #[inline(always)] fn len(&self) -> usize { self.0.len() }
43    #[inline(always)] fn is_empty(&self) -> bool { self.0.is_empty() }
44}
45impl<C: Clear> Clear for Boxed<C> {
46    #[inline(always)] fn clear(&mut self) { self.0.clear() }
47}
48impl<'a, T: ?Sized, C: Container + Push<&'a T>> Push<&'a Box<T>> for Boxed<C> {
49    #[inline(always)] fn push(&mut self, item: &'a Box<T>) { self.0.push(item.as_ref()) }
50    #[inline(always)] fn extend(&mut self, iter: impl IntoIterator<Item=&'a Box<T>>) {
51        self.0.extend(iter.into_iter().map(|x| x.as_ref()))
52    }
53}
54impl<'a, C: Container> Push<Boxed<C::Ref<'a>>> for Boxed<C> {
55    #[inline(always)] fn push(&mut self, item: Boxed<C::Ref<'_>>) { self.0.push(item.0) }
56    #[inline(always)] fn extend(&mut self, iter: impl IntoIterator<Item=Boxed<C::Ref<'a>>>) {
57        self.0.extend(iter.into_iter().map(|x| x.0))
58    }
59}
60impl<'a, C: AsBytes<'a>> AsBytes<'a> for Boxed<C> {
61    const SLICE_COUNT: usize = C::SLICE_COUNT;
62    #[inline] fn get_byte_slice(&self, index: usize) -> (u64, &'a [u8]) { self.0.get_byte_slice(index) }
63}
64impl<'a, C: FromBytes<'a>> FromBytes<'a> for Boxed<C> {
65    const SLICE_COUNT: usize = C::SLICE_COUNT;
66    #[inline(always)] fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self { Self(C::from_bytes(bytes)) }
67    #[inline(always)] fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self { Self(C::from_store(store, offset)) }
68    #[inline(always)] fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> { C::element_sizes(sizes) }
69}
70impl<C: Index> Index for Boxed<C> {
71    type Ref = Boxed<C::Ref>;
72    #[inline(always)] fn get(&self, index: usize) -> Self::Ref { Boxed(self.0.get(index)) }
73}
74impl<C: IndexMut> IndexMut for Boxed<C> {
75    type IndexMut<'a> = Boxed<C::IndexMut<'a>> where Self: 'a;
76    #[inline(always)] fn get_mut(&mut self, index: usize) -> Self::IndexMut<'_> { Boxed(self.0.get_mut(index)) }
77}
78