konst_macro_rules/
into_iter.rs

1use core::{marker::PhantomData, mem::ManuallyDrop};
2
3pub mod range_into_iter;
4pub mod slice_into_iter;
5
6pub trait IntoIterKind {
7    type Kind;
8}
9
10pub struct IsStdKind {}
11
12pub struct IsNonIteratorKind {}
13
14pub struct IsIteratorKind {}
15
16///
17#[repr(transparent)]
18pub struct IntoIterWrapper<I, K> {
19    pub iter: ManuallyDrop<I>,
20    pub marker: IsIntoIterKind<I, K>,
21}
22
23mod is_into_iter_kind {
24    use super::*;
25
26    pub struct IsIntoIterKind<T, K>(PhantomData<(fn() -> PhantomData<T>, fn() -> K)>);
27
28    impl<T> IsIntoIterKind<T, T::Kind>
29    where
30        T: IntoIterKind,
31    {
32        pub const NEW: Self = Self(PhantomData);
33    }
34}
35pub use is_into_iter_kind::IsIntoIterKind;
36
37impl<T> IntoIterWrapper<T, IsStdKind> {
38    #[inline(always)]
39    pub const fn coerce(self) -> Self {
40        self
41    }
42}
43
44impl<T> IntoIterWrapper<T, IsNonIteratorKind> {
45    #[inline(always)]
46    pub const fn coerce(self) -> T {
47        ManuallyDrop::into_inner(self.iter)
48    }
49}
50
51impl<T> IntoIterWrapper<T, IsIteratorKind> {
52    #[inline(always)]
53    pub const fn coerce(self) -> Self {
54        self
55    }
56
57    #[inline(always)]
58    pub const fn const_into_iter(self) -> T {
59        ManuallyDrop::into_inner(self.iter)
60    }
61}
62
63////////////////////////////////////////////////////////////////////////////////
64
65pub struct EmptyIter;
66
67impl EmptyIter {
68    #[inline(always)]
69    pub const fn next(self) -> Option<(core::convert::Infallible, Self)> {
70        None
71    }
72}
73
74impl IntoIterKind for EmptyIter {
75    type Kind = IsIteratorKind;
76}
77
78////////////////////////////////////////////////////////////////////////////////
79
80#[macro_export]
81macro_rules! into_iter_macro {
82    ($iter:expr) => {
83        $crate::__::IntoIterWrapper {
84            iter: $crate::__::ManuallyDrop::new($iter),
85            marker: $crate::__::IsIntoIterKind::NEW,
86        }
87        .coerce()
88        .const_into_iter()
89    };
90}