abi_stable/erased_types/
iterator.rs1use crate::{
2 marker_type::{ErasedObject, NonOwningPhantom},
3 sabi_types::{RMut, RRef},
4 std_types::{RNone, ROption, RSome, RVec, Tuple2},
5 traits::IntoReprC,
6 utils::Transmuter,
7};
8
9#[repr(C)]
12#[derive(StableAbi)]
13pub struct IteratorFns<Item> {
14 pub(super) next: unsafe extern "C" fn(RMut<'_, ErasedObject>) -> ROption<Item>,
15 pub(super) extending_rvec:
16 unsafe extern "C" fn(RMut<'_, ErasedObject>, &mut RVec<Item>, ROption<usize>),
17 pub(super) size_hint:
18 unsafe extern "C" fn(RRef<'_, ErasedObject>) -> Tuple2<usize, ROption<usize>>,
19 pub(super) count: unsafe extern "C" fn(RMut<'_, ErasedObject>) -> usize,
20 pub(super) last: unsafe extern "C" fn(RMut<'_, ErasedObject>) -> ROption<Item>,
21 pub(super) nth: unsafe extern "C" fn(RMut<'_, ErasedObject>, usize) -> ROption<Item>,
22 pub(super) skip_eager: unsafe extern "C" fn(RMut<'_, ErasedObject>, usize),
23}
24
25impl<Item> Copy for IteratorFns<Item> {}
26impl<Item> Clone for IteratorFns<Item> {
27 fn clone(&self) -> Self {
28 *self
29 }
30}
31
32pub struct MakeIteratorFns<I>(NonOwningPhantom<I>);
35
36impl<I> MakeIteratorFns<I>
37where
38 I: Iterator,
39{
40 const ITER: IteratorFns<I::Item> = IteratorFns {
41 next: next::<I>,
42 extending_rvec: extending_rvec::<I>,
43 size_hint: size_hint::<I>,
44 count: count::<I>,
45 last: last::<I>,
46 nth: nth::<I>,
47 skip_eager: skip_eager::<I>,
48 };
49
50 pub(super) const NEW: IteratorFns<()> = unsafe { Transmuter { from: Self::ITER }.to };
51}
52
53pub(super) unsafe extern "C" fn next<I>(this: RMut<'_, ErasedObject>) -> ROption<I::Item>
56where
57 I: Iterator,
58{
59 extern_fn_panic_handling! {no_early_return;
60 let this = unsafe { this.transmute_into_mut::<I>() };
61 this.next().into_c()
62 }
63}
64
65pub(super) unsafe extern "C" fn extending_rvec<I>(
66 this: RMut<'_, ErasedObject>,
67 vec: &mut RVec<I::Item>,
68 taking: ROption<usize>,
69) where
70 I: Iterator,
71{
72 extern_fn_panic_handling! {no_early_return;
73 let this = unsafe { this.transmute_into_mut::<I>() };
74
75 vec.extend(
76 this.take(taking.unwrap_or(!0))
77 );
78 }
79}
80
81pub(super) unsafe extern "C" fn size_hint<I>(
82 this: RRef<'_, ErasedObject>,
83) -> Tuple2<usize, ROption<usize>>
84where
85 I: Iterator,
86{
87 extern_fn_panic_handling! {no_early_return;
88 let this = unsafe { this.transmute_into_ref::<I>() };
89 let (l,r)=this.size_hint();
90
91 Tuple2(l,r.into_c())
92 }
93}
94
95pub(super) unsafe extern "C" fn count<I>(this: RMut<'_, ErasedObject>) -> usize
96where
97 I: Iterator,
98{
99 extern_fn_panic_handling! {no_early_return;
100 let this = unsafe { this.transmute_into_mut::<I>() };
101 this.count()
102 }
103}
104
105pub(super) unsafe extern "C" fn last<I>(this: RMut<'_, ErasedObject>) -> ROption<I::Item>
106where
107 I: Iterator,
108{
109 extern_fn_panic_handling! {no_early_return;
110 let this = unsafe { this.transmute_into_mut::<I>() };
111 this.last().into_c()
112 }
113}
114
115pub(super) unsafe extern "C" fn nth<I>(this: RMut<'_, ErasedObject>, at: usize) -> ROption<I::Item>
116where
117 I: Iterator,
118{
119 extern_fn_panic_handling! {no_early_return;
120 let this = unsafe { this.transmute_into_mut::<I>() };
121 this.nth(at).into_c()
122 }
123}
124
125pub(super) unsafe extern "C" fn skip_eager<I>(this: RMut<'_, ErasedObject>, skipping: usize)
126where
127 I: Iterator,
128{
129 extern_fn_panic_handling! {no_early_return;
130 let this = unsafe { this.transmute_into_mut::<I>() };
131
132 if skipping!=0 {
133 let _=this.nth(skipping-1);
134 }
135 }
136}
137
138#[repr(C)]
143#[derive(StableAbi)]
144pub struct DoubleEndedIteratorFns<Item> {
145 pub(super) next_back: unsafe extern "C" fn(RMut<'_, ErasedObject>) -> ROption<Item>,
146 pub(super) extending_rvec_back:
147 unsafe extern "C" fn(RMut<'_, ErasedObject>, &mut RVec<Item>, ROption<usize>),
148 pub(super) nth_back: unsafe extern "C" fn(RMut<'_, ErasedObject>, usize) -> ROption<Item>,
149}
150
151impl<Item> Copy for DoubleEndedIteratorFns<Item> {}
152impl<Item> Clone for DoubleEndedIteratorFns<Item> {
153 fn clone(&self) -> Self {
154 *self
155 }
156}
157
158pub struct MakeDoubleEndedIteratorFns<I>(NonOwningPhantom<I>);
161
162impl<I> MakeDoubleEndedIteratorFns<I>
163where
164 I: DoubleEndedIterator,
165{
166 pub(super) const ITER: DoubleEndedIteratorFns<I::Item> = DoubleEndedIteratorFns {
167 next_back: next_back::<I>,
168 extending_rvec_back: extending_rvec_back::<I>,
169 nth_back: nth_back::<I>,
170 };
171
172 pub(super) const NEW: DoubleEndedIteratorFns<()> =
173 unsafe { Transmuter { from: Self::ITER }.to };
174}
175
176pub(super) unsafe extern "C" fn next_back<I>(this: RMut<'_, ErasedObject>) -> ROption<I::Item>
179where
180 I: DoubleEndedIterator,
181{
182 extern_fn_panic_handling! {no_early_return;
183 let this = unsafe { this.transmute_into_mut::<I>() };
184 this.next_back().into_c()
185 }
186}
187
188pub(super) unsafe extern "C" fn extending_rvec_back<I>(
189 this: RMut<'_, ErasedObject>,
190 vec: &mut RVec<I::Item>,
191 taking: ROption<usize>,
192) where
193 I: DoubleEndedIterator,
194{
195 extern_fn_panic_handling! {no_early_return;
196 let this = unsafe { this.transmute_into_mut::<I>() };
197
198 vec.extend(
199 this.rev().take(taking.unwrap_or(!0))
200 );
201 }
202}
203
204pub(super) unsafe extern "C" fn nth_back<I>(
205 this: RMut<'_, ErasedObject>,
206 mut at: usize,
207) -> ROption<I::Item>
208where
209 I: DoubleEndedIterator,
210{
211 extern_fn_panic_handling! { let this = unsafe { this.transmute_into_mut::<I>() };
213 for x in this.rev() {
214 if at == 0 {
215 return RSome(x)
216 }
217 at -= 1;
218 }
219 RNone
220 }
221}