Skip to content
This repository was archived by the owner on Nov 27, 2020. It is now read-only.

Commit fbae9d9

Browse files
committed
Implement CloneIn and FromIteratorIn for Vec
1 parent 0dab6e8 commit fbae9d9

File tree

6 files changed

+117
-72
lines changed

6 files changed

+117
-72
lines changed

src/alloc/mod.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,10 @@ use core::{
99
num::NonZeroUsize,
1010
ptr::{self, NonNull},
1111
};
12-
pub use liballoc::alloc::Layout;
12+
pub use liballoc::alloc::{handle_alloc_error, Layout};
1313
#[cfg(feature = "std")]
1414
use std::alloc::System;
1515

16-
/// Abort on memory allocation error or failure.
17-
///
18-
/// Callers of memory allocation APIs wishing to abort computation
19-
/// in response to an allocation error are encouraged to call this function,
20-
/// rather than directly invoking `panic!` or similar.
21-
///
22-
/// The default behavior of this function is to print a message to standard error
23-
/// and abort the process.
24-
/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
25-
///
26-
/// [`set_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.set_alloc_error_hook.html
27-
/// [`take_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.take_alloc_error_hook.html
28-
#[allow(clippy::inline_always)]
29-
#[inline(always)]
30-
#[deprecated = "allocation functions returns an error, use that instead"]
31-
pub fn handle_alloc_error(layout: Layout) -> ! {
32-
liballoc::alloc::handle_alloc_error(layout)
33-
}
34-
3516
/// Allocate memory with the global allocator.
3617
///
3718
/// This function forwards calls to the [`GlobalAlloc::alloc`] method

src/clone.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use crate::alloc::AllocRef;
33
pub trait CloneIn<A: AllocRef>: Sized {
44
type Cloned;
55

6-
fn clone_in(&self, a: A) -> Self::Cloned
7-
where
8-
A: AllocRef;
6+
fn clone_in(&self, a: A) -> Self::Cloned;
97

108
fn try_clone_in(&self, a: A) -> Result<Self::Cloned, A::Error>;
119
}

src/iter.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::{alloc::AllocRef, collections::CollectionAllocErr};
2+
13
/// Extend a collection "fallibly" with the contents of an iterator.
24
pub trait TryExtend<A> {
35
type Err;
@@ -21,3 +23,33 @@ pub trait TryExtend<A> {
2123
/// ```
2224
fn try_extend<T: IntoIterator<Item = A>>(&mut self, iter: T) -> Result<(), Self::Err>;
2325
}
26+
27+
pub trait FromIteratorIn<T, A: AllocRef> {
28+
fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, allocator: A) -> Self;
29+
30+
fn try_from_iter_in<I: IntoIterator<Item = T>>(
31+
iter: I,
32+
allocator: A,
33+
) -> Result<Self, CollectionAllocErr<A>>
34+
where
35+
Self: Sized;
36+
}
37+
38+
pub trait IteratorExt: Iterator + Sized {
39+
#[inline]
40+
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
41+
fn collect_in<T: FromIteratorIn<Self::Item, A>, A: AllocRef>(self, allocator: A) -> T {
42+
FromIteratorIn::from_iter_in(self, allocator)
43+
}
44+
45+
#[inline]
46+
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
47+
fn try_collect_in<T: FromIteratorIn<Self::Item, A>, A: AllocRef>(
48+
self,
49+
allocator: A,
50+
) -> Result<T, CollectionAllocErr<A>> {
51+
FromIteratorIn::try_from_iter_in(self, allocator)
52+
}
53+
}
54+
55+
impl<T> IteratorExt for T where T: Iterator {}

src/raw_vec.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
alloc::{
3+
handle_alloc_error,
34
AllocRef,
45
BuildAllocRef,
56
CapacityOverflow,
@@ -167,7 +168,7 @@ impl<T, A: DeallocRef> RawVec<T, A> {
167168
match Self::try_with_capacity_in(capacity, a) {
168169
Ok(vec) => vec,
169170
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
170-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
171+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
171172
}
172173
}
173174

@@ -202,7 +203,7 @@ impl<T, A: DeallocRef> RawVec<T, A> {
202203
match Self::try_with_capacity_zeroed_in(capacity, a) {
203204
Ok(vec) => vec,
204205
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
205-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
206+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
206207
}
207208
}
208209

@@ -416,7 +417,7 @@ impl<T, A: DeallocRef> RawVec<T, A> {
416417
match self.try_double() {
417418
Ok(_) => (),
418419
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
419-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
420+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
420421
}
421422
}
422423

@@ -586,7 +587,7 @@ impl<T, A: DeallocRef> RawVec<T, A> {
586587
match self.try_reserve(used_capacity, needed_extra_capacity) {
587588
Ok(vec) => vec,
588589
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
589-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
590+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
590591
}
591592
}
592593

src/string.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ use core::{
8080
#[cfg(feature = "std")]
8181
use std::borrow::Cow;
8282

83+
use crate::alloc::handle_alloc_error;
8384
pub use liballoc::string::{ParseError, ToString};
8485

8586
/// A UTF-8 encoded, growable string.
@@ -709,7 +710,7 @@ impl<A: DeallocRef> String<A> {
709710
match Self::try_from_utf8_lossy_in(v, a) {
710711
Ok(s) => s,
711712
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
712-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
713+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
713714
}
714715
}
715716

@@ -1255,7 +1256,7 @@ impl<A: DeallocRef> String<A> {
12551256
match self.try_push(ch) {
12561257
Ok(s) => s,
12571258
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
1258-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
1259+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
12591260
}
12601261
}
12611262

@@ -1507,7 +1508,7 @@ impl<A: DeallocRef> String<A> {
15071508
match self.try_insert(idx, ch) {
15081509
Ok(s) => s,
15091510
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
1510-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
1511+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
15111512
}
15121513
}
15131514

@@ -1582,7 +1583,7 @@ impl<A: DeallocRef> String<A> {
15821583
match self.try_insert_str(idx, string) {
15831584
Ok(s) => s,
15841585
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
1585-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
1586+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
15861587
}
15871588
}
15881589

@@ -1705,7 +1706,7 @@ impl<A: DeallocRef> String<A> {
17051706
match self.try_split_off(at) {
17061707
Ok(s) => s,
17071708
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
1708-
Err(CollectionAllocErr::AllocError { .. }) => unreachable!("Infallible allocation"),
1709+
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
17091710
}
17101711
}
17111712

0 commit comments

Comments
 (0)