Skip to content

Commit

Permalink
More container extensions
Browse files Browse the repository at this point in the history
• impl FromIterator<T> for ABox<[T], A>
• impl Extend<T> for AVec<T, A>
• impl Extend<&T> for AVec<T, A>
• impl FromIterator<T> for AVec<T, A>
• impl Index<SliceIndex<[T]>> for AVec<T, A>
• impl IndexMut<SliceIndex<[T]>> for AVec<T, A>
• impl std::io::Write for AVec<u8, A>
• impl AVec<T, A>::[try_]into_boxed_slice
  • Loading branch information
MaulingMonkey committed May 21, 2023
1 parent 188d7eb commit ba09877
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/boxed/abox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl<T, A: Free> ABox<[MaybeUninit<T>], A> {
// [MaybeUninit<T>]

// XXX: make pub?
#[allow(dead_code)] pub(super) unsafe fn assume_init(self) -> ABox<[T], A> {
pub(crate) unsafe fn assume_init(self) -> ABox<[T], A> {
let (data, allocator) = ABox::into_raw_with_allocator(self);
let data = util::nn::slice_from_raw_parts(data.cast(), data.len());
// SAFETY: ✔️ we just decomposed (data, allocator) from a compatible-layout box
Expand Down
12 changes: 11 additions & 1 deletion src/boxed/abox_traits.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::boxed::ABox;
use crate::fat::*;
use crate::meta::ZstSupported;
use crate::vec::AVec;

use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
Expand Down Expand Up @@ -118,8 +120,16 @@ impl<A: Free> Extend<ABox<str, A>> for alloc::string::String {
}
}

#[cfg(global_oom_handling)]
impl<T, A: Realloc + Default + ZstSupported> FromIterator<T> for ABox<[T], A> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
AVec::<T, A>::from_iter(iter).into_boxed_slice()
}
}

// TODO: FromIterator<ABox<str, A>> for String

// TODO:
// • [ ] impl FromIterator
// • [ ] impl Generator<...>
//
// TODO:
Expand Down
22 changes: 20 additions & 2 deletions src/vec/avec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::error::ExcessiveSliceRequestedError;
use crate::meta::*;
use crate::fat::*;

use core::mem::ManuallyDrop;
use core::mem::MaybeUninit;
use core::ops::{RangeBounds, Bound};

Expand Down Expand Up @@ -44,7 +45,7 @@ impl<T, A: Free> AVec<T, A> {
// TODO: dedup, dedup_by, dedup_by_key
// TODO: drain, drain_filter

/* pub? */ fn try_extend_from_slice(&mut self, slice: &[T]) -> Result<(), A::Error> where T : Clone, A : Realloc {
pub(crate) fn try_extend_from_slice(&mut self, slice: &[T]) -> Result<(), A::Error> where T : Clone, A : Realloc {
self.try_reserve(slice.len())?;
for value in slice.iter().cloned() { unsafe { self.push_within_capacity_unchecked(value) } }
Ok(())
Expand Down Expand Up @@ -77,7 +78,24 @@ impl<T, A: Free> AVec<T, A> {

// TODO: from_raw_parts, from_raw_parts_in
// TODO: insert
// TODO: into_boxed_slice, into_flattened

fn try_into_boxed_slice(self) -> Result<ABox<[T], A>, (Self, A::Error)> where A : Realloc {
let mut v = self;
if let Err(err) = v.try_shrink_to_fit() { return Err((v, err)) }

// decompose without Drop
let v = ManuallyDrop::new(v);
let data = unsafe { std::ptr::read(&v.data) };
core::mem::forget(v);

//let (raw, allocator) = data.into_raw_with_allocator();
//Ok(ABox::from_raw_in(raw, allocator))
Ok(unsafe { data.assume_init() })
}

#[cfg(global_oom_handling)] pub fn into_boxed_slice(self) -> ABox<[T], A> where A : Realloc { self.try_into_boxed_slice().map_err(|(_, err)| err).expect("unable to shrink alloc") }

// TODO: into_flattened
// TODO: into_raw_parts, into_raw_parts_with_allocator
// TODO: leak

Expand Down
60 changes: 54 additions & 6 deletions src/vec/avec_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt::{self, Debug, Formatter};
use core::hash::{Hash, Hasher};
use core::ops::{Deref, DerefMut};
use core::ops::{Deref, DerefMut, Index, IndexMut};
use core::slice::SliceIndex;



Expand Down Expand Up @@ -55,14 +56,61 @@ impl<T: PartialOrd, A: Free> PartialOrd for AVec<T, A> {
#[cfg( global_oom_handling )] impl<T, A: Free + Alloc + Default + ZstSupported > Default for AVec<T, A> { fn default() -> Self { Self::new() } }
#[cfg(not(global_oom_handling))] impl<T, A: Free + Alloc + Default + ZstInfalliable> Default for AVec<T, A> { fn default() -> Self { Self::new() } }

#[cfg(global_oom_handling)] impl<T, A: Realloc + ZstSupported> Extend<T> for AVec<T, A> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let iter = iter.into_iter();
self.reserve(iter.size_hint().0);
for item in iter { self.push(item) }
}
}

#[cfg(global_oom_handling)] impl<'a, T: Copy + 'a, A: Realloc + ZstSupported> Extend<&'a T> for AVec<T, A> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
let iter = iter.into_iter();
self.reserve(iter.size_hint().0);
for item in iter { self.push(*item) }
}
// unstable:
// fn extend_one(&mut self, item: &'a T) { self.push(*item) }
// fn extend_reserve(&mut self, additional: usize) { self.reserve(additional) }
}

// TODO:
// • [ ] Extend
// • [ ] From
// • [ ] FromIterator

#[cfg(global_oom_handling)] impl<T, A: Realloc + Default + ZstSupported> FromIterator<T> for AVec<T, A> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut v = Self::new();
v.extend(iter);
v
}
}

// TODO:
// • [ ] TryFrom
// • [ ] Index
// • [ ] IndexMut

impl<T, A: Free, I: SliceIndex<[T]>> Index<I> for AVec<T, A> {
type Output = I::Output;
fn index(&self, index: I) -> &I::Output { self.as_slice().index(index) }
}

impl<T, A: Free, I: SliceIndex<[T]>> IndexMut<I> for AVec<T, A> {
fn index_mut(&mut self, index: I) -> &mut I::Output { self.as_slice_mut().index_mut(index) }
}

// TODO:
// • [ ] IntoIterator
// TODO:
// • [ ] PartialEq spam
// • [ ] PartialOrd spam
// • [ ] std::io::Write for AVec<u8, A>

#[cfg(feature = "std")]
impl<A: Realloc> std::io::Write for AVec<u8, A> {
fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
match self.try_extend_from_slice(buf) {
Ok(()) => Ok(buf.len()),
Err(_err) => Err(std::io::Error::from(std::io::ErrorKind::OutOfMemory)),
}
}
}

0 comments on commit ba09877

Please sign in to comment.