pub(super) mod iter_eval_helpers;
#[doc(hidden)]
#[macro_export]
macro_rules! __iter_eval {
(
$iter:expr
$($(,)+ $methods:ident ($($args:tt)*))*
$(,)?
) => (
$crate::iter::__eval2_lowering!{
{
// instruction in the current iteration level
//
// Iteration levels are nested iterator loops,
// starts with only one (the one for `$iter`),
[]
[]
[
[
]
[]
[ $iter;]
]
}
$([$methods $methods] ($($args)*))*
}
);
(
$(, $methods:ident ($($args:tt)*))*
$(,)?
) => (
$crate::__::compile_error!{ "expected iterator argument" }
);
}
macro_rules! iter_rev_limitations_docs {
() => {
concat! {
"\n\nIterator-reversing methods can't be called after any of these methods: \n",
"- `enumerate` \n",
"- `map_while` \n",
"- `rev` \n",
"- `skip_while` \n",
"- `skip` \n",
"- `step_by` \n",
"- `take_while` \n",
"- `take` \n",
"- `zip` \n",
}
};
}
pub(super) use iter_rev_limitations_docs;
#[cfg(feature = "cmp")]
macro_rules! iter_cmp_docs {
() => {
concat! {
"\n\nThis is only available with the `\"cmp\"` feature (enabled by default),\n",
"because it uses the [`ConstCmp`](crate::cmp::ConstCmp) trait ",
"for comparing items. \n\n",
"```rust",
}
};
}
#[cfg(not(feature = "cmp"))]
macro_rules! iter_cmp_docs {
() => {
concat! {
"\n\nThis is only available with the `\"cmp\"` feature (enabled by default) \n\n",
"```ignore",
}
};
}
use iter_cmp_docs;
#[doc = crate::docs::closure_arg_annotated_params_options_docs!("")]
#[doc = iter_rev_limitations_docs!()]
#[doc = iter_rev_limitations_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc = self::iter_cmp_docs!()]
#[doc(inline)]
pub use __iter_eval as eval;
declare_eval2_lowering! {
$
# eval methods
(
{ [$($prev_insts:tt)*] $($fixed:tt)* }
[map] ($($args:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{ [ $($prev_insts)* (map (__parse_closure_1) map $($args)*)] $($fixed)* }
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[enumerate] ()
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
map
(__fast_parse_closure_1)
enumerate
|item| -> _ {
let item = (i, item);
i += 1;
item
}
)]
$prev_levels
[$is_returning [$($vars)* mut i = 0usize,] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $($fixed:tt)* }
[copied] ()
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
map
(__fast_parse_closure_1)
copied
|item| -> _ {
let &item = item;
item
}
)]
$($fixed)*
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[skip] ($skipping:expr $(,)?)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
forbids_rev(skip)
|_| {
let _: $crate::__::usize = skipping;
if skipping != 0 {
skipping -= 1;
continue
}
}
)]
$prev_levels
[$is_returning [$($vars)* mut skipping = $skipping,] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[skip_while] ($($closure:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
forbids_rev(skip_while)
|ref item| {
skipping = skipping && $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (skip_while),
$($closure)*
};
if skipping {
continue
}
}
)]
$prev_levels
[$is_returning [$($vars)* mut skipping = true,] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[take] ($taking:expr $(,)?)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
forbids_rev(take)
|_| {
let _: $crate::__::usize = taking;
if taking == 0 {
__iter2_returner!{}
} else {
taking -= 1;
}
}
)]
$prev_levels
[[is_returning] [$($vars)* mut taking = $taking,] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[take_while] ($($closure:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
forbids_rev(take_while)
|ref item| {
taking = taking && $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (take_while),
$($closure)*
};
if !taking {
__iter2_returner!{}
}
}
)]
$prev_levels
[[is_returning] [$($vars)* mut taking = true,] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt $vars:tt $iters:tt] }
[map_while] ($($closure:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[ $($prev_insts)* (map_while $($closure)*)]
$prev_levels
[[is_returning] $vars $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt [$is_returning:tt [$($vars:tt)*] $iters:tt] }
[step_by] ($by:expr $(,)?)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
forbids_rev(step_by)
|_| {
vars.left_to_skip -= 1;
if vars.left_to_skip == 0 {
vars.left_to_skip = vars.step;
} else {
continue;
}
}
)]
$prev_levels
[$is_returning [$($vars)* mut vars = $crate::iter::__StepByVars::new($by),] $iters]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $($fixed:tt)* }
[filter] ($($args:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
__inspector
|ref item| {
let filter_in: $crate::__::bool = $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (filter),
$($args)*
};
if !filter_in {
continue
}
}
)]
$($fixed)*
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $($fixed:tt)* }
[filter_map] ($($args:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (
map
(__fast_parse_closure_1)
filter_map
|item| -> _ {
$crate::if_let_Some!{
item = $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (filter_map),
$($args)*
} => {
item
} else {
continue
}
}
}
)]
$($fixed)*
}
$($rem)*
}
};
(
{
[$($prev_insts:tt)*]
$prev_levels:tt
[ $is_returning:tt $vars:tt [$($iters:tt)*] ]
}
[zip] ($other_iter:expr $(,)?)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[$($prev_insts)* (zip (other_iter))]
$prev_levels
[[is_returning] $vars [$($iters)* other_iter = $other_iter,] ]
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] [$($prev_levels:tt)*] $vars:tt }
[rev] ()
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[
$($prev_insts)*
(rev =>)
]
[
{rev => $($prev_levels)* $($prev_insts)*}
$($prev_levels)*
]
$vars
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] [$($prev_levels:tt)*] $tl_vars:tt}
[flatten] ()
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[]
[
$($prev_levels)*
$($prev_insts)*
(iterate [[] [,use_item;]])
]
$tl_vars
}
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] [$($prev_levels:tt)*] $tl_vars:tt}
[flat_map] ($($args:tt)*)
$($rem:tt)*
) => {
$crate::iter::__eval2_lowering!{
{
[]
[
$($prev_levels)*
$($prev_insts)*
(map (__parse_closure_1) flat_map $($args)*)
(iterate [[] [,use_item;]])
]
$tl_vars
}
$($rem)*
}
};
# consumer methods
( fixed:tt [find] ($($closure:tt)*) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = $crate::__::None, |item| {
let found = $crate::__parse_closure_1!{
($crate::__eval_closure) (&item,) (find),
$($closure)*
};
if found {
$crate::__utils::__overwrite(&mut accum, $crate::__::Some(item));
__iter2_returner!{}
}
})
$($rem)*
}
};
( fixed:tt [rfind] $args:tt $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[rev rev] ()
[find find] $args
$($rem)*
}
};
( fixed:tt [find_map] ($($closure:tt)*) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = $crate::__::None, |item| {
$crate::if_let_Some!{found =
$crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (find_map),
$($closure)*
} => {
$crate::__utils::__overwrite(&mut accum, $crate::__::Some(found));
__iter2_returner!{}
}
}
})
$($rem)*
}
};
( fixed:tt [position] ($($closure:tt)*) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (@vars(mut i = 0usize,) accum = $crate::__::None, |item| {
let found = $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (position),
$($closure)*
};
if found {
accum = $crate::__::Some(i);
__iter2_returner!{}
} else {
i += 1;
}
})
$($rem)*
}
};
( fixed:tt [all] ($($closure:tt)*) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = true, |item| {
accum = $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (all),
$($closure)*
};
if !accum {
__iter2_returner!{}
}
})
$($rem)*
}
};
( fixed:tt [any] ($($closure:tt)*) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = false, |item| {
accum = $crate::__parse_closure_1!{
($crate::__eval_closure) (item,) (any),
$($closure)*
};
if accum {
__iter2_returner!{}
}
})
$($rem)*
}
};
( fixed:tt [nth] ($nth:expr $(,)?) $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (@vars(mut i = $nth,) accum = $crate::__::None, |item| {
let _: $crate::__::usize = i;
if let $crate::__::Some(ni) = $crate::__::usize::checked_sub(i, 1) {
i = ni;
} else {
$crate::__utils::__overwrite(&mut accum, $crate::__::Some(item));
__iter2_returner!{}
}
})
$($rem)*
}
};
( fixed:tt [next] () $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = $crate::__::None, |item| {
$crate::__utils::__overwrite(&mut accum, $crate::__::Some(item));
__iter2_returner!{}
})
$($rem)*
}
};
( fixed:tt [count] () $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[fold fold] (@fast_parse 0usize, |accum, _item| -> _ {
accum + 1
})
$($rem)*
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt $tl_vars:tt }
[for_each] ($($closure:tt)*)
) => {
$crate::__iter2_finish_lowering!{
[]
$prev_levels
$tl_vars
[ $($prev_insts)* (for_each $($closure)*) ]
}
};
(
{ [$($prev_insts:tt)*] $prev_levels:tt $tl_vars:tt }
[reduce] ($($closure:tt)*)
) => {
$crate::__iter2_finish_lowering!{
[accum acc = $crate::__::None]
$prev_levels
$tl_vars
[ $($prev_insts)* (reduce (acc) $($closure)*) ]
}
};
(
{
[$($prev_insts:tt)*]
$prev_levels:tt
[[$($is_returning2:ident $($__ir2:tt)*)?] $vars:tt $iters:tt]
}
[fold] (
$(@uses_break ($accum_name:ident) $(@($uses_break:tt))? )?
$(@fast_parse $(@($fast_parse:tt))? )?
$default_val:expr,
$($closure:tt)*
)
) => {
$crate::__iter2_finish_lowering!{
[accum $($accum_name)? acc = $default_val]
$prev_levels
[
[$( is_returning $($uses_break)? )? $($is_returning2)?]
$vars
$iters
]
[
$($prev_insts)*
(fold
($(__fast_parse_closure_2 $($fast_parse)? )? __parse_closure_2)
($($accum_name)? acc)
$($closure)*
)
]
}
};
( fixed:tt [rfold] $args:tt $($rem:tt)* ) => {
$crate::iter::__eval2_lowering!{
$fixed
[rev rev] ()
[fold fold] $args
$($rem)*
}
};
(fixed:tt [cmp] ($other_iter:expr $(,)?)) => {
match $other_iter {other_iter => {
let mut other_iter = $crate::iter::into_iter!(other_iter);
let ord = $crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = $crate::__::Equal, |l_item| {
$crate::if_let_Some!{r_item = other_iter.next() => {
$crate::__iter2_require_cmp!{
"iterator comparison methods require the \"cmp\" feature";
accum = $crate::cmp::const_cmp!(l_item, r_item);
}
if !$crate::__::matches!(accum, $crate::__::Equal) {
__iter2_returner!{}
}
} else {
accum = $crate::__::Greater;
__iter2_returner!{}
}}
})
};
if let $crate::__::Equal = ord
&& let Some(_) = other_iter.next()
{
$crate::__::Less
} else {
ord
}
}}
};
(fixed:tt [eq] ($other_iter:expr $(,)?)) => {
match $other_iter {other_iter => {
let mut other_iter = $crate::iter::into_iter!(other_iter);
let is_eq = $crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (accum = true, |l_item| {
$crate::if_let_Some!{r_item = other_iter.next() => {
$crate::__iter2_require_cmp!{
"iterator comparison methods require the \"cmp\" feature";
if !$crate::cmp::const_eq!(l_item, r_item) {
accum = false;
__iter2_returner!{}
}
}
} else {
accum = false;
__iter2_returner!{}
}}
})
};
is_eq && matches!(other_iter.next(), $crate::__::None)
}}
};
(fixed:tt [ne] ($other_iter:expr $(,)?)) => {
!$crate::iter::__eval2_lowering!{$fixed [eq eq] ($other_iter)}
};
(fixed:tt [ge] ($other_iter:expr $(,)?)) => {
$crate::__::matches!{
$crate::iter::__eval2_lowering!{$fixed [cmp cmp] ($other_iter)},
$crate::__::Greater | $crate::__::Equal
}
};
(fixed:tt [gt] ($other_iter:expr $(,)?)) => {
$crate::__::matches!{
$crate::iter::__eval2_lowering!{$fixed [cmp cmp] ($other_iter)},
$crate::__::Greater
}
};
(fixed:tt [le] ($other_iter:expr $(,)?)) => {
$crate::__::matches!{
$crate::iter::__eval2_lowering!{$fixed [cmp cmp] ($other_iter)},
$crate::__::Less | $crate::__::Equal
}
};
(fixed:tt [lt] ($other_iter:expr $(,)?)) => {
$crate::__::matches!{
$crate::iter::__eval2_lowering!{$fixed [cmp cmp] ($other_iter)},
$crate::__::Less
}
};
(fixed:tt [is_sorted] ()) => {
$crate::__iter2_is_sorted_impl!{
$fixed (l_item, r_item) {};
$crate::__::matches!(
$crate::cmp::const_cmp!(l_item, r_item),
$crate::__::Less | $crate::__::Equal
)
}
};
(fixed:tt [is_sorted_by] ($($closure:tt)*)) => {
$crate::__iter2_is_sorted_impl!{
$fixed (l_item, r_item) {};
$crate::__parse_closure_2!(
($crate::__eval_closure) ((&l_item, &r_item),) (is_sorted_by),
$($closure)*
)
}
};
(fixed:tt [is_sorted_by_key] ($($closure:tt)*)) => {
$crate::__iter2_is_sorted_impl!{
$fixed (l_item, r_item)
{
let r_item = $crate::__parse_closure_1!{
($crate::__eval_closure) (r_item,) (@default(0u8) is_sorted_by_key),
$($closure)*
};
};
$crate::__::matches!(
$crate::cmp::const_cmp!(l_item, r_item),
$crate::__::Less | $crate::__::Equal
)
}
};
(fixed:tt [max] ()) => {
$crate::__iter2_minmax_impl!{
$fixed (l_item, r_item) ($crate::__::Less | $crate::__::Equal) {};
$crate::cmp::const_cmp!(l_item, r_item)
}
};
(fixed:tt [min] ()) => {
$crate::__iter2_minmax_impl!{
$fixed (l_item, r_item) ($crate::__::Greater) {};
$crate::cmp::const_cmp!(l_item, r_item)
}
};
(fixed:tt [max_by] ($($closure:tt)*)) => {
$crate::__iter2_minmax_impl!{
$fixed (l_item, r_item) ($crate::__::Less | $crate::__::Equal) {};
$crate::__parse_closure_2!(
($crate::__eval_closure) ((&l_item, &r_item),) (max_by),
$($closure)*
)
}
};
(fixed:tt [min_by] ($($closure:tt)*)) => {
$crate::__iter2_minmax_impl!{
$fixed (l_item, r_item) ($crate::__::Greater) {};
$crate::__parse_closure_2!(
($crate::__eval_closure) ((&l_item, &r_item),) (min_by),
$($closure)*
)
}
};
(fixed:tt [max_by_key] ($($closure:tt)*)) => {
$crate::__iter2_minmax_by_key_impl!{
$fixed [max_by_key] ($($closure)*) ($crate::__::Less | $crate::__::Equal)
}
};
(fixed:tt [min_by_key] ($($closure:tt)*)) => {
$crate::__iter2_minmax_by_key_impl!{
$fixed [min_by_key] ($($closure)*) ($crate::__::Greater)
}
};
# secret methods
(
{
[$($prev_insts:tt)*]
$prev_levels:tt
[$is_returning:tt [$($vars:tt)*] $iters:tt]
}
[__finder] (
$(@vars($($more_vars:tt)*))?
$accum:ident = $default_val:expr,
$($closure:tt)*
)
) => {
$crate::__iter2_finish_lowering!{
[accum $accum = $default_val]
$prev_levels
[[is_returning] [$($vars)* $($($more_vars)*)?] $iters]
[
$($prev_insts)*
(__finder $($closure)*)
]
}
};
(
{
[$($prev_insts:tt)*]
$prev_levels:tt
[$is_returning:tt [$($vars:tt)*] $iters:tt]
}
[__inspector] (
$(@vars($($more_vars:tt)*))?
$($accum:ident = $default_val:expr)?,
$($closure:tt)*
)
) => {
$crate::__iter2_finish_lowering!{
[accum $accum = $default_val]
$prev_levels
[$is_returning [$($vars)* $($($more_vars)*)?] $iters]
[
$($prev_insts)*
(__inspector $($closure)*)
]
}
};
}
macro_rules! declare_eval2_lowering {
(
$_:tt
# eval methods
$(
(
$($state0:ident :tt)? $({$($state0b:tt)*})?
[$eval_method:ident] $($eval_m_args:tt)*
) => {
$($eval_m_expansion:tt)*
};
)*
# consumer methods
$(
(
$($state1:ident :tt)? $({$($state1b:tt)*})?
[$cons_method:ident] $($cons_m_args:tt)*
) => {
$($cons_m_expansion:tt)*
};
)*
# secret methods
$(
(
$($state2:ident :tt)? $({$($state2b:tt)*})?
[$secret_method:ident] $($secret_m_args:tt)*
) => {
$($secret_m_expansion:tt)*
};
)*
) => (
#[doc(hidden)]
#[macro_export]
macro_rules! __eval2_lowering_ {
($fixed:tt [$method_name:ident] $_($rem:tt)*) => {
$crate::__::compile_error!{
"bug: expected `$method_name` argument to be written exactly twice"
}
};
$(
(
$($_ $state0)? $({$($state0b)*})?
[$method_name:ident $eval_method] $($eval_m_args)*
) => {
$($eval_m_expansion)*
};
)*
(
$fixed:tt
[$method_name:ident $( $_($cons_method)? )*]
$args:tt
$_($rem:tt)+
) => {
$crate::__::compile_error!{$crate::__::concat!{
"Cannot consume the iterator multiple times, ",
"first consumed by `", $crate::__::stringify!($method_name) ,
"` method"
}}
};
$(
(
$($_ $state1:tt)? $({$($state1b)*})?
[$method_name:ident $cons_method] $($cons_m_args)*
) => {
$($cons_m_expansion)*
};
)*
$(
(
$($_ $state2:tt)? $({$($state2b)*})?
[$secret_name:ident $secret_method] $($secret_m_args)*
) => {
$($secret_m_expansion)*
};
)*
(
$fixed:tt
[$method_name:ident $( $_($eval_method)? )* $( $_($cons_method)? )*]
($_($args:tt)*)
$_($rem:tt)*
) => {
$crate::__::compile_error!{$crate::__::concat!{
"invalid argument(s) for `", $crate::__::stringify!($method_name),
"` method: `", $crate::__::stringify!($_($args)*), "`"
}}
};
(
$fixed:tt
[$method_name:ident $__method_name:ident]
$_($rem:tt)*
) => {
$crate::__::compile_error!{$crate::__::concat!{
"method `", $crate::__::stringify!($method_name),
"` is unsupported, expected one of:",
$( "\n- ", $crate::__::stringify!($eval_method), )*
$( "\n- ", $crate::__::stringify!($cons_method), )*
}}
};
(
$fixed:tt
) => {
$crate::__::compile_error!{$crate::__::concat!{
"expected one of these consumer methods at the end:",
$( "\n- ", $crate::__::stringify!($cons_method), )*
}}
};
(
$_($rem:tt)+
) => {
$crate::__::compile_error!{$crate::__::concat!{
"Invalid iter::eval lowering syntax: ", $crate::__::stringify!($_($rem)*)
}}
};
}
pub use __eval2_lowering_ as __eval2_lowering;
)
}
use declare_eval2_lowering;
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_finish_lowering {
(
// top-level properties
[$(accum $ret_var:ident $($__ret_var:ident)* = $ret_val:expr)?]
[
$({rev $($rev:tt)*})*
$(($($prev_levels:tt)*))*
]
[
[$($is_returning:ident $($__ir2:tt)*)?]
$vars:tt
$iters:tt
]
[$($instrs_il:tt)*]
) => { match ($($ret_val)?) {($(mut $ret_var)?) => {
$( let mut $is_returning = false; )?
$(
macro_rules! __iter2_returner {
() => {
$is_returning = true;
break;
}
}
)?
$crate::__iter2_interpreter!{
[item next next_back ($($is_returning)?)]
[item next next_back ($($is_returning)?)]
$((rev $($rev)*))*
(iterate @top_level [$vars $iters])
$(($($prev_levels)*))*
$($instrs_il)*
}
$($ret_var)?
}}};
(
$($rem:tt)+
) => {
$crate::__::compile_error!{$crate::__::concat!{
"Invalid iter::eval finish lowering syntax: ", $crate::__::stringify!($($rem)*)
}}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_interpreter {
(
[$item:ident $next:ident $__next_back:ident ($($is_returning:ident $(@$isr:tt)?)?)]
$fixed:tt
(
iterate
$(@top_level $(@($top_level:tt))?)?
[
[$($var_name:pat_param = $var_val:expr,)*]
[
$($iter0_val:expr)? $(,use_item $($__use_item:ident)?)?;
$($iter_name:ident = $iter_val:expr,)*
]
]
)
$($rem:tt)*
) => {
match (
$($var_val,)*
$crate::__::ManuallyDrop::new($($iter0_val)? $($item $(@$__use_item)?)?),
$($crate::__::ManuallyDrop::new($iter_val),)*
) {
($($var_name,)* iter0, $($iter_name,)*) => {
let mut iter0 = $crate::iter::into_iter!(
$crate::__::ManuallyDrop::into_inner(iter0)
);
$(
let mut $iter_name =
$crate::iter::into_iter!($crate::__::ManuallyDrop::into_inner($iter_name));
)*
let elem_phantom_ty = $crate::iter::__get_item_ty(&iter0);
$crate::while_let_Some! { $item = iter0.$next() =>
$crate::iter::__assert_item_ty(&$item, elem_phantom_ty);
$crate::__iter2_interpreter!{
$fixed
$fixed
$($rem)*
}
}
#[cfg(any(false $(, true$($isr)?)?))]
{
$crate::__iter2_drop_iterator!{iter0};
$( $crate::__iter2_drop_iterator!{$iter_name}; )*
}
$crate::__::forget(iter0);
$($crate::__::forget($iter_name);)*
#[cfg(all(true $(, false $($top_level)?)?))]
{
$(
if $is_returning {
break;
}
)?
}
}
}
};
(
[$item:ident $next:ident $($__rem_fixed:tt)*]
$fixed:tt
(
map
($closure_parser:ident $($__closure_parser:tt)*)
$method_name:ident
$($closure:tt)*
)
$($rem:tt)*
) => {
let $item = $crate::$closure_parser!{
($crate::__eval_closure) ($item,) ($method_name),
$($closure)*
};
$crate::__iter2_interpreter!{$fixed $fixed $($rem)*}
};
(
[$item:ident $next:ident $($__rem_fixed:tt)*]
$fixed:tt
(zip ($other_iter:ident))
$($rem:tt)*
) => {
let $item = $crate::if_let_Some!{item2 = $other_iter.$next() => {
($item, item2)
} else {
__iter2_returner!{}
}};
$crate::__iter2_interpreter!{
$fixed
$fixed
$($rem)*
}
};
(
[$item:ident $next:ident $($__rem_fixed:tt)*]
$fixed:tt
(forbids_rev ($method:ident) |$item_param:pat_param| $code:block)
$($rem:tt)*
) => {
let $item_param = $item;
$code
$crate::__iter2_interpreter!{$fixed $fixed $($rem)*}
};
(
[$item:ident $next:ident $($__rem_fixed:tt)*]
$fixed:tt
(map_while $($closure:tt)*)
$($rem:tt)*
) => {
let $item = $crate::if_let_Some!{item =
$crate::__parse_closure_1!{
($crate::__eval_closure) ($item,) (map_while),
$($closure)*
} => {
item
} else {
__iter2_returner!{}
}
};
$crate::__iter2_interpreter!{$fixed $fixed $($rem)*}
};
(
[$item:ident $next:ident $next_back:ident $is_returning:tt]
$fixed:tt
(rev => $($prev_instructions:tt)* )
$($rem:tt)*
) => {
$crate::__iter2_rev_asserts!{$($prev_instructions)*}
$crate::__iter2_interpreter!{
[$item $next_back $next $is_returning]
[$item $next_back $next $is_returning]
$($rem)*
}
};
(
[$item:ident $($__rem_fixed:tt)*]
$fixed:tt
(__inspector |$item_param:pat_param| $code:block)
$($rem:tt)*
) => {
let $item_param = $item;
$code
$crate::__iter2_interpreter!{$fixed $fixed $($rem)*}
};
(
[$item:ident $($__rem_fixed:tt)*]
$fixed:tt
(for_each $($closure:tt)*)
) => {
let _: () = $crate::__parse_closure_1!{
($crate::__eval_closure) ($item,) (for_each),
$($closure)*
};
};
(
[$item:ident $($__rem_fixed:tt)*]
$fixed:tt
(
fold
($closure_parser:ident $($__closure_parser:tt)*)
($acc:ident $($__acc:ident)*)
$($closure:tt)*
)
) => {
$acc = $crate::$closure_parser!{
($crate::__eval_closure) (($acc, $item,),) (fold),
$($closure)*
};
};
(
[$item:ident $($__rem_fixed:tt)*]
$fixed:tt
(reduce ($acc:ident) $($closure:tt)*)
) => {
if false {
$crate::iter::__infer_option_ty(&$acc, &$item);
}
$acc = $crate::__::Some($crate::if_let_Some!{acc = $acc => {
$crate::__parse_closure_2!{
($crate::__eval_closure) ((acc, $item,),) (reduce),
$($closure)*
}
} else {
$item
}})
};
(
[$item:ident $($__rem_fixed:tt)*]
$fixed:tt
(__finder |$item_param:pat_param| $code:block)
) => {
let $item_param = $item;
$code
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_is_sorted_impl {
(
$fixed:tt ($l_item:ident, $r_item:ident)
{$($convert_item_into_key:tt)*};
$comparator:expr
) => {
$crate::iter::__eval2_lowering!{
$fixed
[__finder __finder] (@vars(mut prev = None,) accum = true, |$r_item| {
$($convert_item_into_key)*
if false {
$crate::__utils::__infer_option_of(&$r_item, &prev)
}
$crate::if_let_Some!{$l_item = prev => {
$crate::__iter2_require_cmp!{
"is_sorted methods require the \"cmp\" feature";
if !$comparator {
accum = false;
__iter2_returner!{}
}
}
}}
prev = $crate::__::Some($r_item);
})
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_minmax_impl {
(
$fixed:tt ($l_item:ident, $r_item:ident) ($update_if:pat)
{$($convert_item_into_key:tt)*};
$minmaximizer:expr
) => {
$crate::iter::__eval2_lowering!{
$fixed
[fold fold] (None, |mut prev, $r_item| {
$($convert_item_into_key)*
if false {
$crate::__utils::__infer_option_of(&$r_item, &prev)
}
$crate::if_let_Some!{$l_item = prev => {
$crate::__iter2_require_cmp!{
"min/max methods require the \"cmp\" feature";
if let $update_if = $minmaximizer {
prev = $crate::__::Some($r_item);
}
}
} else {
prev = $crate::__::Some($r_item);
}}
prev
})
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_minmax_by_key_impl {
($fixed:tt [$method_name:ident] ($($closure:tt)*) ($update_if:pat) ) => {
$crate::option::map!(
$crate::__iter2_minmax_impl!{
$fixed (l_item, r_item) ($update_if)
{
let r_item = (
$crate::__parse_closure_1!{
($crate::__eval_closure) (&r_item,) (@default(0u8) $method_name),
$($closure)*
},
r_item,
);
};
$crate::cmp::const_cmp!(l_item.0, r_item.0)
},
|(_key, max)| max
)
};
}
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "cmp")]
macro_rules! __iter2_require_cmp {
($error_msg:expr; $($code:tt)*) => { $($code)* }
}
#[doc(hidden)]
#[macro_export]
#[cfg(not(feature = "cmp"))]
macro_rules! __iter2_require_cmp {
($error_msg:expr; $($code:tt)*) => {
$crate::__::compile_error! {$error_msg}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_drop_iterator {
($iter:ident) => {
if $crate::iter::__items_needs_drop(&$iter) {
while let $crate::__::Some(_) = $iter.next() {}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_rev_asserts {
( $({rev $(@$is_rev:tt)? => $($__0:tt)*})? $(( $($instruction:tt)* ))* ) => {
$(
$crate::__::compile_error!{"iterators can't be reversed twice"};
$(@$is_rev)?
)?
$crate::__iter2_rev_assert_no_truncation!{
$(( $($instruction)* ))*
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __iter2_rev_assert_no_truncation {
(
(forbids_rev ($method_name:ident) $($__0:tt)*)
$($rem:tt)*
) => {
$crate::__::compile_error!{$crate::__::concat!{
"Cannot call `rev()` after calling `",
$crate::__::stringify!($method_name),
"`",
}}
$crate::__iter2_rev_assert_no_truncation!{ $($rem)* }
};
((map $args:tt enumerate $($_01:tt)*) $($rem:tt)*) => {
$crate::__::compile_error!{"Cannot call `rev()` after calling `enumerate`"}
$crate::__iter2_rev_assert_no_truncation!{ $($rem)* }
};
((map_while $($_01:tt)*) $($rem:tt)*) => {
$crate::__::compile_error!{"Cannot call `rev()` after calling `map_while`"}
$crate::__iter2_rev_assert_no_truncation!{ $($rem)* }
};
((zip $($_01:tt)*) $($rem:tt)*) => {
$crate::__::compile_error!{"Cannot call `rev()` after calling `zip`"}
$crate::__iter2_rev_assert_no_truncation!{ $($rem)* }
};
(
($method_name:ident $($__0:tt)*)
$($rem:tt)*
) => {
$crate::__iter2_rev_assert_no_truncation!{ $($rem)* }
};
() => {};
}