|
| 1 | +use crate::const_closure::ConstFnMutClosure; |
| 2 | +use crate::marker::Destruct; |
1 | 3 | use crate::ops::{ControlFlow, Try};
|
2 | 4 |
|
3 | 5 | /// An iterator able to yield elements from both ends.
|
@@ -37,6 +39,7 @@ use crate::ops::{ControlFlow, Try};
|
37 | 39 | /// ```
|
38 | 40 | #[stable(feature = "rust1", since = "1.0.0")]
|
39 | 41 | #[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")]
|
| 42 | +#[const_trait] |
40 | 43 | pub trait DoubleEndedIterator: Iterator {
|
41 | 44 | /// Removes and returns an element from the end of the iterator.
|
42 | 45 | ///
|
@@ -131,9 +134,15 @@ pub trait DoubleEndedIterator: Iterator {
|
131 | 134 | /// [`Err(k)`]: Err
|
132 | 135 | #[inline]
|
133 | 136 | #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
134 |
| - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { |
135 |
| - for i in 0..n { |
| 137 | + fn advance_back_by(&mut self, n: usize) -> Result<(), usize> |
| 138 | + where |
| 139 | + Self::Item: ~const Destruct, |
| 140 | + { |
| 141 | + // FIXME(const_trait_impl): revert back to for loop |
| 142 | + let mut i = 0; |
| 143 | + while i < n { |
136 | 144 | self.next_back().ok_or(i)?;
|
| 145 | + i += 1; |
137 | 146 | }
|
138 | 147 | Ok(())
|
139 | 148 | }
|
@@ -181,7 +190,10 @@ pub trait DoubleEndedIterator: Iterator {
|
181 | 190 | /// ```
|
182 | 191 | #[inline]
|
183 | 192 | #[stable(feature = "iter_nth_back", since = "1.37.0")]
|
184 |
| - fn nth_back(&mut self, n: usize) -> Option<Self::Item> { |
| 193 | + fn nth_back(&mut self, n: usize) -> Option<Self::Item> |
| 194 | + where |
| 195 | + Self::Item: ~const Destruct, |
| 196 | + { |
185 | 197 | self.advance_back_by(n).ok()?;
|
186 | 198 | self.next_back()
|
187 | 199 | }
|
@@ -221,8 +233,9 @@ pub trait DoubleEndedIterator: Iterator {
|
221 | 233 | fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
222 | 234 | where
|
223 | 235 | Self: Sized,
|
224 |
| - F: FnMut(B, Self::Item) -> R, |
225 |
| - R: Try<Output = B>, |
| 236 | + F: ~const FnMut(B, Self::Item) -> R + ~const Destruct, |
| 237 | + R: ~const Try<Output = B>, |
| 238 | + Self::Item: ~const Destruct, |
226 | 239 | {
|
227 | 240 | let mut accum = init;
|
228 | 241 | while let Some(x) = self.next_back() {
|
@@ -291,8 +304,9 @@ pub trait DoubleEndedIterator: Iterator {
|
291 | 304 | #[stable(feature = "iter_rfold", since = "1.27.0")]
|
292 | 305 | fn rfold<B, F>(mut self, init: B, mut f: F) -> B
|
293 | 306 | where
|
294 |
| - Self: Sized, |
295 |
| - F: FnMut(B, Self::Item) -> B, |
| 307 | + Self: Sized + ~const Destruct, |
| 308 | + F: ~const FnMut(B, Self::Item) -> B + ~const Destruct, |
| 309 | + Self::Item: ~const Destruct, |
296 | 310 | {
|
297 | 311 | let mut accum = init;
|
298 | 312 | while let Some(x) = self.next_back() {
|
@@ -344,19 +358,21 @@ pub trait DoubleEndedIterator: Iterator {
|
344 | 358 | /// ```
|
345 | 359 | #[inline]
|
346 | 360 | #[stable(feature = "iter_rfind", since = "1.27.0")]
|
347 |
| - fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> |
| 361 | + fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item> |
348 | 362 | where
|
349 | 363 | Self: Sized,
|
350 |
| - P: FnMut(&Self::Item) -> bool, |
| 364 | + P: ~const FnMut(&Self::Item) -> bool + ~const Destruct, |
| 365 | + Self::Item: ~const Destruct, |
351 | 366 | {
|
352 | 367 | #[inline]
|
353 |
| - fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> { |
354 |
| - move |(), x| { |
355 |
| - if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } |
356 |
| - } |
| 368 | + const fn check<T: ~const Destruct, F: ~const FnMut(&T) -> bool>( |
| 369 | + predicate: &mut F, |
| 370 | + ((), x): ((), T), |
| 371 | + ) -> ControlFlow<T> { |
| 372 | + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } |
357 | 373 | }
|
358 | 374 |
|
359 |
| - self.try_rfold((), check(predicate)).break_value() |
| 375 | + self.try_rfold((), ConstFnMutClosure::new(&mut predicate, check)).break_value() |
360 | 376 | }
|
361 | 377 | }
|
362 | 378 |
|
|
0 commit comments