1use crate::ops::{Decrement, Increment, Indirection};
2use crate::{CppBox, CppDeletable, Ref};
3use std::os::raw::c_char;
4
5pub struct CppIterator<T1, T2>
11where
12 T1: CppDeletable,
13 T2: CppDeletable,
14{
15 begin: CppBox<T1>,
16 end: CppBox<T2>,
17}
18
19pub unsafe fn cpp_iter<T1, T2>(begin: CppBox<T1>, end: CppBox<T2>) -> CppIterator<T1, T2>
27where
28 T1: CppDeletable,
29 T2: CppDeletable,
30{
31 CppIterator { begin, end }
32}
33
34impl<T1, T2> Iterator for CppIterator<T1, T2>
35where
36 T1: CppDeletable + PartialEq<Ref<T2>> + Indirection + Increment,
37 T2: CppDeletable,
38{
39 type Item = <T1 as Indirection>::Output;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 unsafe {
43 if self.begin == self.end.as_ref() {
44 None
45 } else {
46 let inner = &mut *self.begin.as_mut_raw_ptr();
47 let value = inner.indirection();
48 let inner = &mut *self.begin.as_mut_raw_ptr();
49 inner.inc();
50 Some(value)
51 }
52 }
53 }
54}
55
56impl<T1, T2> DoubleEndedIterator for CppIterator<T1, T2>
57where
58 T1: CppDeletable + PartialEq<Ref<T2>> + Indirection + Increment,
59 T2: CppDeletable + Decrement + Indirection<Output = <T1 as Indirection>::Output>,
60{
61 fn next_back(&mut self) -> Option<Self::Item> {
62 unsafe {
63 if self.begin == self.end.as_ref() {
64 None
65 } else {
66 let inner = &mut *self.end.as_mut_raw_ptr();
67 inner.dec();
68 let inner = &mut *self.end.as_mut_raw_ptr();
69 let value = inner.indirection();
70 Some(value)
71 }
72 }
73 }
74}
75
76pub trait EndPtr {
78 type Item;
80 fn end_ptr(&self) -> *const Self::Item;
82}
83
84impl<'a, T> EndPtr for &'a [T] {
85 type Item = T;
86 fn end_ptr(&self) -> *const T {
87 unsafe { self.as_ptr().add(self.len()) }
88 }
89}
90
91impl<'a> EndPtr for &'a str {
92 type Item = c_char;
93 fn end_ptr(&self) -> *const c_char {
94 unsafe { self.as_ptr().add(self.len()) as *const c_char }
95 }
96}