-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
implement FromIterator<char> for Box<str> #65168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
c481236
a0a313c
7192b0c
b268827
ab689ea
048710a
0fad2a6
c73c4b4
f2f9eec
b10277a
e773b20
4ddbf8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,129 @@ | |
| //! | ||
| //! # Examples | ||
| //! | ||
| 1 | ||
| //! A pointer type for heap allocation. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like our docs might still be a little confused here, because they've changed on Would you like to try squashing your 12 commits down and rebase on |
||
| 2 | ||
| //! | ||
| 3 | ||
| //! [`Box<T>`], casually referred to as a 'box', provides the simplest form of | ||
| 4 | ||
| //! heap allocation in Rust. Boxes provide ownership for this allocation, and | ||
| 5 | ||
| //! drop their contents when they go out of scope. | ||
| 6 | ||
| //! | ||
| 7 | ||
| //! # Examples | ||
| 8 | ||
| //! | ||
| 9 | ||
| //! Move a value from the stack to the heap by creating a [`Box`]: | ||
| 10 | ||
| //! | ||
| 11 | ||
| //! ``` | ||
| 12 | ||
| //! let val: u8 = 5; | ||
| 13 | ||
| //! let boxed: Box<u8> = Box::new(val); | ||
| 14 | ||
| //! ``` | ||
| 15 | ||
| //! | ||
| 16 | ||
| //! Move a value from a [`Box`] back to the stack by [dereferencing]: | ||
| 17 | ||
| //! | ||
| 18 | ||
| //! ``` | ||
| 19 | ||
| //! let boxed: Box<u8> = Box::new(5); | ||
| 20 | ||
| //! let val: u8 = *boxed; | ||
| 21 | ||
| //! ``` | ||
| 22 | ||
| //! | ||
| 23 | ||
| //! Creating a recursive data structure: | ||
| 24 | ||
| //! | ||
| 25 | ||
| //! ``` | ||
| 26 | ||
| //! #[derive(Debug)] | ||
| 27 | ||
| //! enum List<T> { | ||
| 28 | ||
| //! Cons(T, Box<List<T>>), | ||
| 29 | ||
| //! Nil, | ||
| 30 | ||
| //! } | ||
| 31 | ||
| //! | ||
| 32 | ||
| //! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); | ||
| 33 | ||
| //! println!("{:?}", list); | ||
| 34 | ||
| //! ``` | ||
| 35 | ||
| //! | ||
| 36 | ||
| //! This will print `Cons(1, Cons(2, Nil))`. | ||
| 37 | ||
| //! | ||
| 38 | ||
| //! Recursive structures must be boxed, because if the definition of `Cons` | ||
| 39 | ||
| //! looked like this: | ||
| 40 | ||
| //! | ||
| 41 | ||
| //! ```compile_fail,E0072 | ||
| 42 | ||
| //! # enum List<T> { | ||
| 43 | ||
| //! Cons(T, List<T>), | ||
| 44 | ||
| //! # } | ||
| 45 | ||
| //! ``` | ||
| 46 | ||
| //! | ||
| 47 | ||
| //! It wouldn't work. This is because the size of a `List` depends on how many | ||
| 48 | ||
| //! elements are in the list, and so we don't know how much memory to allocate | ||
| 49 | ||
| //! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know how | ||
| 50 | ||
| //! big `Cons` needs to be. | ||
| 51 | ||
| //! | ||
| 52 | ||
| //! # Memory layout | ||
| 53 | ||
| //! | ||
| 54 | ||
| //! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for | ||
| 55 | ||
| //! its allocation. It is valid to convert both ways between a [`Box`] and a | ||
| 56 | ||
| //! raw pointer allocated with the [`Global`] allocator, given that the | ||
| 57 | ||
| //! [`Layout`] used with the allocator is correct for the type. More precisely, | ||
| 58 | ||
| //! a `value: *mut T` that has been allocated with the [`Global`] allocator | ||
| 59 | ||
| //! with `Layout::for_value(&*value)` may be converted into a box using | ||
| 60 | ||
| //! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut | ||
| 61 | ||
| //! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the | ||
|
|
||
| //! Move a value from the stack to the heap by creating a [`Box`]: | ||
| //! | ||
| //! ``` | ||
|
|
@@ -95,6 +218,7 @@ use core::task::{Context, Poll}; | |
| use crate::alloc::{self, Global, Alloc}; | ||
| use crate::vec::Vec; | ||
| use crate::raw_vec::RawVec; | ||
| use crate::string::String; | ||
| use crate::str::from_boxed_utf8_unchecked; | ||
|
|
||
| /// A pointer type for heap allocation. | ||
|
|
@@ -1070,3 +1194,10 @@ impl<F: ?Sized + Future + Unpin> Future for Box<F> { | |
| F::poll(Pin::new(&mut *self), cx) | ||
| } | ||
| } | ||
|
|
||
| #[stable(feature = "box_str_from_iter", since = "1.40.0")] | ||
| impl FromIterator<char> for Box<str> { | ||
| fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Box<str> { | ||
| String::from_iter(iter).into_boxed_str() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,3 +151,12 @@ fn test_array_from_slice() { | |
| let a: Result<Box<[u32; 2]>, _> = r.clone().try_into(); | ||
| assert!(a.is_err()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn box_str_from_iter(){ | ||
| let iter = (0..100).map(|_|{'☺'}); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ☺ |
||
| let string: Box<str> = iter.collect(); | ||
|
|
||
| assert_eq!(string.chars().count(), 100); | ||
| assert_eq!(string.chars().nth(5), Some('☺')); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.