|
1 | 1 | use core::async_iter::AsyncIterator; |
2 | | -use core::iter::FusedIterator; |
| 2 | +use core::iter::{FusedIterator, TrustedLen}; |
| 3 | +use core::num::NonZero; |
3 | 4 | use core::pin::Pin; |
4 | 5 | use core::slice; |
5 | 6 | use core::task::{Context, Poll}; |
6 | 7 |
|
7 | | -use crate::alloc::Allocator; |
| 8 | +use crate::alloc::{Allocator, Global}; |
8 | 9 | #[cfg(not(no_global_oom_handling))] |
9 | 10 | use crate::borrow::Cow; |
10 | 11 | use crate::boxed::Box; |
11 | 12 | #[cfg(not(no_global_oom_handling))] |
12 | 13 | use crate::string::String; |
13 | | -use crate::vec; |
14 | 14 | #[cfg(not(no_global_oom_handling))] |
15 | 15 | use crate::vec::Vec; |
| 16 | +use crate::{fmt, vec}; |
16 | 17 |
|
17 | 18 | #[stable(feature = "rust1", since = "1.0.0")] |
18 | 19 | impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> { |
@@ -192,3 +193,154 @@ impl<'a> FromIterator<Cow<'a, str>> for Box<str> { |
192 | 193 | String::from_iter(iter).into_boxed_str() |
193 | 194 | } |
194 | 195 | } |
| 196 | + |
| 197 | +/// This implementation is required to make sure that the `Box<[I; N]>: IntoIterator` |
| 198 | +/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. |
| 199 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 200 | +impl<I, const N: usize, A: Allocator> !Iterator for Box<[I; N], A> {} |
| 201 | + |
| 202 | +/// This implementation is required to make sure that the `&Box<[I; N]>: IntoIterator` |
| 203 | +/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. |
| 204 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 205 | +impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a Box<[I; N], A> {} |
| 206 | + |
| 207 | +/// This implementation is required to make sure that the `&mut Box<[I; N]>: IntoIterator` |
| 208 | +/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. |
| 209 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 210 | +impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a mut Box<[I; N], A> {} |
| 211 | + |
| 212 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 213 | +impl<'a, T, const N: usize, A: Allocator> IntoIterator for &'a Box<[T; N], A> { |
| 214 | + type IntoIter = slice::Iter<'a, T>; |
| 215 | + type Item = &'a T; |
| 216 | + fn into_iter(self) -> slice::Iter<'a, T> { |
| 217 | + self.iter() |
| 218 | + } |
| 219 | +} |
| 220 | + |
| 221 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 222 | +impl<'a, T, const N: usize, A: Allocator> IntoIterator for &'a mut Box<[T; N], A> { |
| 223 | + type IntoIter = slice::IterMut<'a, T>; |
| 224 | + type Item = &'a mut T; |
| 225 | + fn into_iter(self) -> slice::IterMut<'a, T> { |
| 226 | + self.iter_mut() |
| 227 | + } |
| 228 | +} |
| 229 | + |
| 230 | +/// A by-value `Box<[T; N]>` iterator. |
| 231 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 232 | +#[rustc_insignificant_dtor] |
| 233 | +pub struct BoxedArrayIntoIter<T, const N: usize, A: Allocator = Global> { |
| 234 | + // FIXME: make a more efficient implementation (without the need to store capacity) |
| 235 | + inner: vec::IntoIter<T, A>, |
| 236 | +} |
| 237 | + |
| 238 | +impl<T, const N: usize, A: Allocator> BoxedArrayIntoIter<T, N, A> { |
| 239 | + /// Returns an immutable slice of all elements that have not been yielded |
| 240 | + /// yet. |
| 241 | + #[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 242 | + pub fn as_slice(&self) -> &[T] { |
| 243 | + self.inner.as_slice() |
| 244 | + } |
| 245 | + |
| 246 | + /// Returns a mutable slice of all elements that have not been yielded yet. |
| 247 | + #[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 248 | + pub fn as_mut_slice(&mut self) -> &mut [T] { |
| 249 | + self.inner.as_mut_slice() |
| 250 | + } |
| 251 | +} |
| 252 | + |
| 253 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 254 | +impl<T, const N: usize, A: Allocator> Iterator for BoxedArrayIntoIter<T, N, A> { |
| 255 | + type Item = T; |
| 256 | + fn next(&mut self) -> Option<Self::Item> { |
| 257 | + self.inner.next() |
| 258 | + } |
| 259 | + |
| 260 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 261 | + let len = self.len(); |
| 262 | + (len, Some(len)) |
| 263 | + } |
| 264 | + |
| 265 | + #[inline] |
| 266 | + fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
| 267 | + where |
| 268 | + Fold: FnMut(Acc, Self::Item) -> Acc, |
| 269 | + { |
| 270 | + self.inner.fold(init, fold) |
| 271 | + } |
| 272 | + |
| 273 | + fn count(self) -> usize { |
| 274 | + self.len() |
| 275 | + } |
| 276 | + |
| 277 | + fn last(mut self) -> Option<Self::Item> { |
| 278 | + self.next_back() |
| 279 | + } |
| 280 | + |
| 281 | + fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
| 282 | + self.inner.advance_by(n) |
| 283 | + } |
| 284 | +} |
| 285 | + |
| 286 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 287 | +impl<T, const N: usize, A: Allocator> DoubleEndedIterator for BoxedArrayIntoIter<T, N, A> { |
| 288 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 289 | + self.inner.next_back() |
| 290 | + } |
| 291 | + |
| 292 | + #[inline] |
| 293 | + fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc |
| 294 | + where |
| 295 | + Fold: FnMut(Acc, Self::Item) -> Acc, |
| 296 | + { |
| 297 | + self.inner.rfold(init, rfold) |
| 298 | + } |
| 299 | + |
| 300 | + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
| 301 | + self.inner.advance_back_by(n) |
| 302 | + } |
| 303 | +} |
| 304 | + |
| 305 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 306 | +impl<T, const N: usize, A: Allocator> ExactSizeIterator for BoxedArrayIntoIter<T, N, A> { |
| 307 | + fn len(&self) -> usize { |
| 308 | + self.inner.len() |
| 309 | + } |
| 310 | + |
| 311 | + fn is_empty(&self) -> bool { |
| 312 | + self.inner.is_empty() |
| 313 | + } |
| 314 | +} |
| 315 | + |
| 316 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 317 | +impl<T, const N: usize, A: Allocator> FusedIterator for BoxedArrayIntoIter<T, N, A> {} |
| 318 | + |
| 319 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 320 | +unsafe impl<T, const N: usize, A: Allocator> TrustedLen for BoxedArrayIntoIter<T, N, A> {} |
| 321 | + |
| 322 | +#[cfg(not(no_global_oom_handling))] |
| 323 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 324 | +impl<T: Clone, const N: usize, A: Clone + Allocator> Clone for BoxedArrayIntoIter<T, N, A> { |
| 325 | + fn clone(&self) -> Self { |
| 326 | + Self { inner: self.inner.clone() } |
| 327 | + } |
| 328 | +} |
| 329 | + |
| 330 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 331 | +impl<T: fmt::Debug, const N: usize, A: Allocator> fmt::Debug for BoxedArrayIntoIter<T, N, A> { |
| 332 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 333 | + // Only print the elements that were not yielded yet: we cannot |
| 334 | + // access the yielded elements anymore. |
| 335 | + f.debug_tuple("BoxedArrayIntoIter").field(&self.as_slice()).finish() |
| 336 | + } |
| 337 | +} |
| 338 | + |
| 339 | +#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")] |
| 340 | +impl<T, const N: usize, A: Allocator> IntoIterator for Box<[T; N], A> { |
| 341 | + type IntoIter = BoxedArrayIntoIter<T, N, A>; |
| 342 | + type Item = T; |
| 343 | + fn into_iter(self) -> BoxedArrayIntoIter<T, N, A> { |
| 344 | + BoxedArrayIntoIter { inner: (self as Box<[T], A>).into_vec().into_iter() } |
| 345 | + } |
| 346 | +} |
0 commit comments