Implement more iterator functions / traits in custom iterators for efficiency reasons

This commit is contained in:
Sebastian Dröge 2022-05-20 16:58:46 +03:00
parent 8f1c94f45d
commit d4430ecc6a
15 changed files with 739 additions and 186 deletions

View file

@ -255,25 +255,58 @@ impl Iterator for AudioFormatIterator {
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.len { let remaining = self.len - self.idx;
return (0, Some(0));
}
let remaining = (self.len - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some(AUDIO_FORMATS_ALL[end])
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some(AUDIO_FORMATS_ALL[self.len - 1])
}
}
} }
impl ExactSizeIterator for AudioFormatIterator {} impl ExactSizeIterator for AudioFormatIterator {}
impl std::iter::FusedIterator for AudioFormatIterator {}
impl DoubleEndedIterator for AudioFormatIterator { impl DoubleEndedIterator for AudioFormatIterator {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
if self.idx >= self.len { if self.idx >= self.len {
None None
} else { } else {
let fmt = AUDIO_FORMATS_ALL[self.len - 1];
self.len -= 1; self.len -= 1;
let fmt = AUDIO_FORMATS_ALL[self.len];
Some(fmt)
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
let fmt = AUDIO_FORMATS_ALL[self.len];
Some(fmt) Some(fmt)
} }
} }

View file

@ -44,3 +44,5 @@ impl DiscovererStreamInfo {
} }
} }
} }
impl std::iter::FusedIterator for Iter {}

View file

@ -656,8 +656,8 @@ macro_rules! define_iter(
#[derive(Debug)] #[derive(Debug)]
pub struct $name<'a> { pub struct $name<'a> {
media: &'a SDPMediaRef, media: &'a SDPMediaRef,
idx: u32, idx: usize,
len: u32, len: usize,
} }
impl<'a> $name<'a> { impl<'a> $name<'a> {
@ -668,7 +668,7 @@ macro_rules! define_iter(
$name { $name {
media, media,
idx: 0, idx: 0,
len, len: len as usize,
} }
} }
} }
@ -681,20 +681,40 @@ macro_rules! define_iter(
return None; return None;
} }
let item = $get_item(self.media, self.idx)?; let item = $get_item(self.media, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.len { let remaining = self.len - self.idx;
return (0, Some(0))
}
let remaining = (self.len - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some($get_item(self.media, end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some($get_item(self.media, self.len as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -705,11 +725,24 @@ macro_rules! define_iter(
self.len -= 1; self.len -= 1;
$get_item(self.media, self.len) Some($get_item(self.media, self.len as u32).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
Some($get_item(self.media, self.len as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );

View file

@ -1009,8 +1009,8 @@ macro_rules! define_iter(
#[derive(Debug)] #[derive(Debug)]
pub struct $name<'a> { pub struct $name<'a> {
message: &'a SDPMessageRef, message: &'a SDPMessageRef,
idx: u32, idx: usize,
len: u32, len: usize,
} }
impl<'a> $name<'a> { impl<'a> $name<'a> {
@ -1021,7 +1021,7 @@ macro_rules! define_iter(
$name { $name {
message, message,
idx: 0, idx: 0,
len, len: len as usize,
} }
} }
} }
@ -1034,20 +1034,39 @@ macro_rules! define_iter(
return None; return None;
} }
let item = $get_item(self.message, self.idx)?; let item = $get_item(self.message, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.len { let remaining = self.len - self.idx;
return (0, Some(0))
}
let remaining = (self.len - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some($get_item(self.message, end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some($get_item(self.message, self.len as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -1058,11 +1077,23 @@ macro_rules! define_iter(
self.len -= 1; self.len -= 1;
$get_item(self.message, self.len) Some($get_item(self.message, self.len as u32).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
Some($get_item(self.message, self.len as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );
@ -1071,8 +1102,8 @@ macro_rules! define_iter_mut(
#[derive(Debug)] #[derive(Debug)]
pub struct $name<'a> { pub struct $name<'a> {
message: &'a mut SDPMessageRef, message: &'a mut SDPMessageRef,
idx: u32, idx: usize,
len: u32, len: usize,
} }
impl<'a> $name<'a> { impl<'a> $name<'a> {
@ -1083,7 +1114,7 @@ macro_rules! define_iter_mut(
$name { $name {
message, message,
idx: 0, idx: 0,
len, len: len as usize,
} }
} }
} }
@ -1108,20 +1139,43 @@ macro_rules! define_iter_mut(
return None; return None;
} }
let item = $get_item(message, self.idx)?; let item = $get_item(message, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.len { let remaining = self.len - self.idx;
return (0, Some(0))
}
let remaining = (self.len - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let message = unsafe {
&mut *(self.message as *mut SDPMessageRef)
};
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some($get_item(message, end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some($get_item(self.message, self.len as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -1134,12 +1188,27 @@ macro_rules! define_iter_mut(
} }
self.len -= 1; self.len -= 1;
Some($get_item(message, self.len as u32).unwrap())
}
$get_item(message, self.len)
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let message = unsafe {
&mut *(self.message as *mut SDPMessageRef)
};
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
Some($get_item(message, self.len as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );

View file

@ -354,10 +354,35 @@ impl Iterator for VideoFormatIterator {
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some(VIDEO_FORMATS_ALL[end])
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some(VIDEO_FORMATS_ALL[self.len - 1])
}
}
} }
impl ExactSizeIterator for VideoFormatIterator {} impl ExactSizeIterator for VideoFormatIterator {}
impl std::iter::FusedIterator for VideoFormatIterator {}
impl DoubleEndedIterator for VideoFormatIterator { impl DoubleEndedIterator for VideoFormatIterator {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
if self.idx >= self.len { if self.idx >= self.len {
@ -368,6 +393,18 @@ impl DoubleEndedIterator for VideoFormatIterator {
Some(fmt) Some(fmt)
} }
} }
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
let fmt = VIDEO_FORMATS_ALL[self.len];
Some(fmt)
}
}
} }
pub trait VideoFormatIteratorExt { pub trait VideoFormatIteratorExt {
fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>>; fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>>;

View file

@ -361,7 +361,7 @@ impl VideoRegionOfInterestMeta {
pub fn params(&self) -> ParamsIter { pub fn params(&self) -> ParamsIter {
ParamsIter { ParamsIter {
_meta: self, _meta: self,
list: self.0.params, list: ptr::NonNull::new(self.0.params),
} }
} }
@ -395,29 +395,29 @@ impl VideoRegionOfInterestMeta {
pub struct ParamsIter<'a> { pub struct ParamsIter<'a> {
_meta: &'a VideoRegionOfInterestMeta, _meta: &'a VideoRegionOfInterestMeta,
list: *const glib::ffi::GList, list: Option<ptr::NonNull<glib::ffi::GList>>,
} }
impl<'a> Iterator for ParamsIter<'a> { impl<'a> Iterator for ParamsIter<'a> {
type Item = &'a gst::StructureRef; type Item = &'a gst::StructureRef;
fn next(&mut self) -> Option<&'a gst::StructureRef> { fn next(&mut self) -> Option<&'a gst::StructureRef> {
if self.list.is_null() { match self.list {
return None; None => None,
} Some(list) => unsafe {
self.list = ptr::NonNull::new(list.as_ref().next);
let data = list.as_ref().data;
unsafe { let s = gst::StructureRef::from_glib_borrow(data as *const gst::ffi::GstStructure);
let data = (*self.list).data;
assert!(!data.is_null());
self.list = (*self.list).next;
let s = gst::StructureRef::from_glib_borrow(data as *const gst::ffi::GstStructure); Some(s)
},
Some(s)
} }
} }
} }
impl<'a> std::iter::FusedIterator for ParamsIter<'a> {}
unsafe impl MetaAPI for VideoRegionOfInterestMeta { unsafe impl MetaAPI for VideoRegionOfInterestMeta {
type GstType = ffi::GstVideoRegionOfInterestMeta; type GstType = ffi::GstVideoRegionOfInterestMeta;

View file

@ -328,7 +328,7 @@ impl VideoOverlayCompositionRef {
Iter { Iter {
composition: self, composition: self,
idx: 0, idx: 0,
len: self.n_rectangles(), len: self.n_rectangles() as usize,
} }
} }
} }
@ -390,33 +390,52 @@ impl<'a> std::iter::FromIterator<&'a VideoOverlayRectangle> for VideoOverlayComp
pub struct Iter<'a> { pub struct Iter<'a> {
composition: &'a VideoOverlayCompositionRef, composition: &'a VideoOverlayCompositionRef,
idx: u32, idx: usize,
len: u32, len: usize,
} }
impl<'a> Iterator for Iter<'a> { impl<'a> Iterator for Iter<'a> {
type Item = VideoOverlayRectangle; type Item = VideoOverlayRectangle;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.idx == self.len { if self.idx >= self.len {
return None; return None;
} }
let rect = self.composition.rectangle(self.idx).unwrap(); let rect = self.composition.rectangle(self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(rect) Some(rect)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.len { let remaining = self.len - self.idx;
return (0, Some(0));
}
let remaining = (self.len - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.len - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.len || overflow {
self.idx = self.len;
None
} else {
self.idx = end + 1;
Some(self.composition.rectangle(end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.len {
None
} else {
Some(self.composition.rectangle(self.len as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
@ -427,10 +446,21 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
self.len -= 1; self.len -= 1;
let rect = self.composition.rectangle(self.len).unwrap(); Some(self.composition.rectangle(self.len as u32).unwrap())
}
Some(rect) fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.len.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.len;
None
} else {
self.len = end - 1;
Some(self.composition.rectangle(self.len as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for Iter<'a> {} impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> std::iter::FusedIterator for Iter<'a> {}

View file

@ -816,6 +816,8 @@ macro_rules! define_meta_iter(
} }
} }
} }
impl<'a, T: MetaAPI> std::iter::FusedIterator for $name<'a, T> { }
} }
); );
@ -838,8 +840,8 @@ macro_rules! define_iter(
($name:ident, $typ:ty, $mtyp:ty, $get_item:expr) => { ($name:ident, $typ:ty, $mtyp:ty, $get_item:expr) => {
pub struct $name<'a> { pub struct $name<'a> {
buffer: $typ, buffer: $typ,
idx: u32, idx: usize,
n_memory: u32, n_memory: usize,
} }
impl<'a> fmt::Debug for $name<'a> { impl<'a> fmt::Debug for $name<'a> {
@ -861,7 +863,7 @@ macro_rules! define_iter(
$name { $name {
buffer, buffer,
idx: 0, idx: 0,
n_memory, n_memory: n_memory as usize,
} }
} }
} }
@ -876,21 +878,46 @@ macro_rules! define_iter(
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
let item = $get_item(self.buffer, self.idx)?; let item = $get_item(self.buffer, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.n_memory { let remaining = self.n_memory - self.idx;
return (0, Some(0));
}
let remaining = (self.n_memory - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.n_memory - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_memory || overflow {
self.idx = self.n_memory;
None
} else {
#[allow(unused_unsafe)]
unsafe {
self.idx = end + 1;
Some($get_item(self.buffer, end as u32).unwrap())
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_memory {
None
} else {
#[allow(unused_unsafe)]
unsafe {
Some($get_item(self.buffer, self.n_memory as u32 - 1).unwrap())
}
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -899,16 +926,31 @@ macro_rules! define_iter(
return None; return None;
} }
self.n_memory -= 1;
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
$get_item(self.buffer, self.n_memory) self.n_memory -= 1;
Some($get_item(self.buffer, self.n_memory as u32).unwrap())
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_memory.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_memory;
None
} else {
#[allow(unused_unsafe)]
unsafe {
self.n_memory = end - 1;
Some($get_item(self.buffer, self.n_memory as u32).unwrap())
}
} }
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );

View file

@ -215,8 +215,8 @@ macro_rules! define_iter(
#[derive(Debug)] #[derive(Debug)]
pub struct $name<'a> { pub struct $name<'a> {
list: &'a BufferListRef, list: &'a BufferListRef,
idx: u32, idx: usize,
size: u32, size: usize,
} }
impl<'a> $name<'a> { impl<'a> $name<'a> {
@ -225,7 +225,7 @@ macro_rules! define_iter(
$name { $name {
list, list,
idx: 0, idx: 0,
size: list.len() as u32, size: list.len() as usize,
} }
} }
} }
@ -238,21 +238,40 @@ macro_rules! define_iter(
return None; return None;
} }
let item = $get_item(self.list, self.idx)?; let item = $get_item(self.list, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
Some($get_item(self.list, end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
Some($get_item(self.list, self.size as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -262,11 +281,23 @@ macro_rules! define_iter(
} }
self.size -= 1; self.size -= 1;
$get_item(self.list, self.size) Some($get_item(self.list, self.size as u32).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
Some($get_item(self.list, self.size as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );

View file

@ -597,8 +597,8 @@ macro_rules! define_iter(
#[derive(Debug)] #[derive(Debug)]
pub struct $name<'a> { pub struct $name<'a> {
caps: $typ, caps: $typ,
idx: u32, idx: usize,
n_structures: u32, n_structures: usize,
} }
impl<'a> $name<'a> { impl<'a> $name<'a> {
@ -609,7 +609,7 @@ macro_rules! define_iter(
$name { $name {
caps, caps,
idx: 0, idx: 0,
n_structures, n_structures: n_structures as usize,
} }
} }
} }
@ -623,21 +623,44 @@ macro_rules! define_iter(
} }
unsafe { unsafe {
let item = $get_item(self.caps, self.idx)?; let item = $get_item(self.caps, self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(item) Some(item)
} }
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.n_structures { let remaining = self.n_structures - self.idx;
return (0, Some(0));
}
let remaining = (self.n_structures - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.n_structures - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_structures || overflow {
self.idx = self.n_structures;
None
} else {
unsafe {
self.idx = end + 1;
Some($get_item(self.caps, end as u32).unwrap())
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_structures {
None
} else {
unsafe {
Some($get_item(self.caps, self.n_structures as u32 - 1).unwrap())
}
}
}
} }
impl<'a> DoubleEndedIterator for $name<'a> { impl<'a> DoubleEndedIterator for $name<'a> {
@ -649,12 +672,27 @@ macro_rules! define_iter(
self.n_structures -= 1; self.n_structures -= 1;
unsafe { unsafe {
$get_item(self.caps, self.n_structures) Some($get_item(self.caps, self.n_structures as u32).unwrap())
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_structures.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_structures;
None
} else {
self.n_structures = end - 1;
unsafe {
Some($get_item(self.caps, self.n_structures as u32).unwrap())
}
} }
} }
} }
impl<'a> ExactSizeIterator for $name<'a> {} impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
} }
); );

View file

@ -479,8 +479,8 @@ impl glib::value::ToValueOptional for CapsFeaturesRef {
#[derive(Debug)] #[derive(Debug)]
pub struct Iter<'a> { pub struct Iter<'a> {
caps_features: &'a CapsFeaturesRef, caps_features: &'a CapsFeaturesRef,
idx: u32, idx: usize,
n_features: u32, n_features: usize,
} }
impl<'a> Iter<'a> { impl<'a> Iter<'a> {
@ -491,7 +491,7 @@ impl<'a> Iter<'a> {
Iter { Iter {
caps_features, caps_features,
idx: 0, idx: 0,
n_features, n_features: n_features as usize,
} }
} }
} }
@ -505,10 +505,9 @@ impl<'a> Iterator for Iter<'a> {
} }
unsafe { unsafe {
let feature = ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.idx); let feature =
if feature.is_null() { ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.idx as u32);
return None; assert!(!feature.is_null());
}
self.idx += 1; self.idx += 1;
@ -517,14 +516,46 @@ impl<'a> Iterator for Iter<'a> {
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.n_features { let remaining = self.n_features - self.idx;
return (0, Some(0));
}
let remaining = (self.n_features - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.n_features - self.idx
}
// checker-ignore-item
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_features || overflow {
self.idx = self.n_features;
None
} else {
unsafe {
self.idx = end + 1;
let feature =
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), end as u32);
assert!(!feature.is_null());
Some(CStr::from_ptr(feature).to_str().unwrap())
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_features {
None
} else {
unsafe {
let feature = ffi::gst_caps_features_get_nth(
self.caps_features.as_ptr(),
self.n_features as u32 - 1,
);
assert!(!feature.is_null());
Some(CStr::from_ptr(feature).to_str().unwrap())
}
}
}
} }
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
@ -537,18 +568,37 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
unsafe { unsafe {
let feature = let feature =
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features); ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features as u32);
if feature.is_null() { assert!(!feature.is_null());
return None;
}
Some(CStr::from_ptr(feature).to_str().unwrap()) Some(CStr::from_ptr(feature).to_str().unwrap())
} }
} }
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_features.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_features;
None
} else {
unsafe {
self.n_features = end - 1;
let feature = ffi::gst_caps_features_get_nth(
self.caps_features.as_ptr(),
self.n_features as u32,
);
assert!(!feature.is_null());
Some(CStr::from_ptr(feature).to_str().unwrap())
}
}
}
} }
impl<'a> ExactSizeIterator for Iter<'a> {} impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> std::iter::FusedIterator for Iter<'a> {}
impl<'a> IntoIterator for &'a CapsFeaturesRef { impl<'a> IntoIterator for &'a CapsFeaturesRef {
type IntoIter = Iter<'a>; type IntoIter = Iter<'a>;
type Item = &'a str; type Item = &'a str;

View file

@ -691,6 +691,8 @@ where
} }
} }
impl<T> iter::FusedIterator for StdIterator<T> where for<'a> T: FromValue<'a> + 'static {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -13,8 +13,8 @@ use std::mem::transmute;
#[derive(Debug)] #[derive(Debug)]
pub struct Iter<'a> { pub struct Iter<'a> {
collection: &'a StreamCollection, collection: &'a StreamCollection,
idx: u32, idx: usize,
size: u32, size: usize,
} }
impl<'a> Iter<'a> { impl<'a> Iter<'a> {
@ -23,7 +23,7 @@ impl<'a> Iter<'a> {
Iter { Iter {
collection, collection,
idx: 0, idx: 0,
size: collection.len() as u32, size: collection.len() as usize,
} }
} }
} }
@ -36,21 +36,40 @@ impl<'a> Iterator for Iter<'a> {
return None; return None;
} }
let item = self.collection.stream(self.idx); let item = self.collection.stream(self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
item Some(item)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
Some(self.collection.stream(end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
Some(self.collection.stream(self.size as u32 - 1).unwrap())
}
}
} }
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
@ -60,12 +79,25 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
} }
self.size -= 1; self.size -= 1;
self.collection.stream(self.size) Some(self.collection.stream(self.size as u32).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
Some(self.collection.stream(self.size as u32).unwrap())
}
} }
} }
impl<'a> ExactSizeIterator for Iter<'a> {} impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> std::iter::FusedIterator for Iter<'a> {}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[must_use = "The builder must be built to be used"] #[must_use = "The builder must be built to be used"]
pub struct StreamCollectionBuilder(StreamCollection); pub struct StreamCollectionBuilder(StreamCollection);

View file

@ -852,8 +852,8 @@ impl glib::value::ToValueOptional for StructureRef {
#[derive(Debug)] #[derive(Debug)]
pub struct FieldIterator<'a> { pub struct FieldIterator<'a> {
structure: &'a StructureRef, structure: &'a StructureRef,
idx: u32, idx: usize,
n_fields: u32, n_fields: usize,
} }
impl<'a> FieldIterator<'a> { impl<'a> FieldIterator<'a> {
@ -864,7 +864,7 @@ impl<'a> FieldIterator<'a> {
FieldIterator { FieldIterator {
structure, structure,
idx: 0, idx: 0,
n_fields, n_fields: n_fields as usize,
} }
} }
} }
@ -877,20 +877,14 @@ impl<'a> Iterator for FieldIterator<'a> {
return None; return None;
} }
if let Some(field_name) = self.structure.nth_field_name(self.idx) { let field_name = self.structure.nth_field_name(self.idx as u32).unwrap();
self.idx += 1; self.idx += 1;
Some(field_name)
} else { Some(field_name)
None
}
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.n_fields { let remaining = self.n_fields - self.idx;
return (0, Some(0));
}
let remaining = (self.n_fields - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
@ -903,12 +897,14 @@ impl<'a> DoubleEndedIterator for FieldIterator<'a> {
} }
self.n_fields -= 1; self.n_fields -= 1;
self.structure.nth_field_name(self.n_fields) Some(self.structure.nth_field_name(self.n_fields as u32).unwrap())
} }
} }
impl<'a> ExactSizeIterator for FieldIterator<'a> {} impl<'a> ExactSizeIterator for FieldIterator<'a> {}
impl<'a> std::iter::FusedIterator for FieldIterator<'a> {}
#[derive(Debug)] #[derive(Debug)]
pub struct Iter<'a> { pub struct Iter<'a> {
iter: FieldIterator<'a>, iter: FieldIterator<'a>,
@ -927,32 +923,51 @@ impl<'a> Iterator for Iter<'a> {
type Item = (&'static str, &'a SendValue); type Item = (&'static str, &'a SendValue);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if let Some(f) = self.iter.next() { let f = self.iter.next()?;
let v = self.iter.structure.value(f); let v = self.iter.structure.value(f);
Some((f, v.unwrap())) Some((f, v.unwrap()))
} else {
None
}
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint() self.iter.size_hint()
} }
fn count(self) -> usize {
self.iter.count()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth(n)?;
let v = self.iter.structure.value(f);
Some((f, v.unwrap()))
}
fn last(self) -> Option<Self::Item> {
let structure = self.iter.structure;
let f = self.iter.last()?;
let v = structure.value(f);
Some((f, v.unwrap()))
}
} }
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
if let Some(f) = self.iter.next_back() { let f = self.iter.next_back()?;
let v = self.iter.structure.value(f); let v = self.iter.structure.value(f);
Some((f, v.unwrap())) Some((f, v.unwrap()))
} else { }
None
} fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth_back(n)?;
let v = self.iter.structure.value(f);
Some((f, v.unwrap()))
} }
} }
impl<'a> ExactSizeIterator for Iter<'a> {} impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> std::iter::FusedIterator for Iter<'a> {}
impl<'a> IntoIterator for &'a StructureRef { impl<'a> IntoIterator for &'a StructureRef {
type IntoIter = Iter<'a>; type IntoIter = Iter<'a>;
type Item = (&'static str, &'a SendValue); type Item = (&'static str, &'a SendValue);

View file

@ -606,8 +606,8 @@ impl Eq for TagListRef {}
#[derive(Debug)] #[derive(Debug)]
pub struct TagIter<'a, T: Tag<'a>> { pub struct TagIter<'a, T: Tag<'a>> {
taglist: &'a TagListRef, taglist: &'a TagListRef,
idx: u32, idx: usize,
size: u32, size: usize,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
@ -617,7 +617,7 @@ impl<'a, T: Tag<'a>> TagIter<'a, T> {
TagIter { TagIter {
taglist, taglist,
idx: 0, idx: 0,
size: taglist.size::<T>(), size: taglist.size::<T>() as usize,
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -635,21 +635,40 @@ where
return None; return None;
} }
let item = self.taglist.index::<T>(self.idx); let item = self.taglist.index::<T>(self.idx as u32);
self.idx += 1; self.idx += 1;
item item
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
self.taglist.index::<T>(end as u32)
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
self.taglist.index::<T>(self.size as u32 - 1)
}
}
} }
impl<'a, T: Tag<'a>> DoubleEndedIterator for TagIter<'a, T> impl<'a, T: Tag<'a>> DoubleEndedIterator for TagIter<'a, T>
@ -663,7 +682,18 @@ where
} }
self.size -= 1; self.size -= 1;
self.taglist.index::<T>(self.size) self.taglist.index::<T>(self.size as u32)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
self.taglist.index::<T>(self.size as u32)
}
} }
} }
@ -674,12 +704,19 @@ where
{ {
} }
impl<'a, T: Tag<'a>> std::iter::FusedIterator for TagIter<'a, T>
where
<T as Tag<'a>>::TagType: 'a,
T: 'a,
{
}
#[derive(Debug)] #[derive(Debug)]
pub struct GenericTagIter<'a> { pub struct GenericTagIter<'a> {
taglist: &'a TagListRef, taglist: &'a TagListRef,
name: &'a str, name: &'a str,
idx: u32, idx: usize,
size: u32, size: usize,
} }
impl<'a> GenericTagIter<'a> { impl<'a> GenericTagIter<'a> {
@ -689,7 +726,7 @@ impl<'a> GenericTagIter<'a> {
taglist, taglist,
name, name,
idx: 0, idx: 0,
size: taglist.size_by_name(name), size: taglist.size_by_name(name) as usize,
} }
} }
} }
@ -702,21 +739,40 @@ impl<'a> Iterator for GenericTagIter<'a> {
return None; return None;
} }
let item = self.taglist.index_generic(self.name, self.idx); let item = self.taglist.index_generic(self.name, self.idx as u32);
self.idx += 1; self.idx += 1;
item item
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
self.taglist.index_generic(self.name, end as u32)
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
self.taglist.index_generic(self.name, self.size as u32 - 1)
}
}
} }
impl<'a> DoubleEndedIterator for GenericTagIter<'a> { impl<'a> DoubleEndedIterator for GenericTagIter<'a> {
@ -726,17 +782,30 @@ impl<'a> DoubleEndedIterator for GenericTagIter<'a> {
} }
self.size -= 1; self.size -= 1;
self.taglist.index_generic(self.name, self.size) self.taglist.index_generic(self.name, self.size as u32)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
self.taglist.index_generic(self.name, self.size as u32)
}
} }
} }
impl<'a> ExactSizeIterator for GenericTagIter<'a> {} impl<'a> ExactSizeIterator for GenericTagIter<'a> {}
impl<'a> std::iter::FusedIterator for GenericTagIter<'a> {}
#[derive(Debug)] #[derive(Debug)]
pub struct GenericIter<'a> { pub struct GenericIter<'a> {
taglist: &'a TagListRef, taglist: &'a TagListRef,
idx: u32, idx: usize,
size: u32, size: usize,
} }
impl<'a> GenericIter<'a> { impl<'a> GenericIter<'a> {
@ -746,7 +815,7 @@ impl<'a> GenericIter<'a> {
GenericIter { GenericIter {
taglist, taglist,
idx: 0, idx: 0,
size: if size > 0 { size as u32 } else { 0 }, size: if size > 0 { size as usize } else { 0 },
} }
} }
} }
@ -759,7 +828,7 @@ impl<'a> Iterator for GenericIter<'a> {
return None; return None;
} }
let name = self.taglist.nth_tag_name(self.idx); let name = self.taglist.nth_tag_name(self.idx as u32);
let item = (name, self.taglist.iter_tag_generic(name)); let item = (name, self.taglist.iter_tag_generic(name));
self.idx += 1; self.idx += 1;
@ -767,14 +836,35 @@ impl<'a> Iterator for GenericIter<'a> {
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
let name = self.taglist.nth_tag_name(end as u32);
Some((name, self.taglist.iter_tag_generic(name)))
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
let name = self.taglist.nth_tag_name(self.size as u32 - 1);
Some((name, self.taglist.iter_tag_generic(name)))
}
}
} }
impl<'a> DoubleEndedIterator for GenericIter<'a> { impl<'a> DoubleEndedIterator for GenericIter<'a> {
@ -784,18 +874,32 @@ impl<'a> DoubleEndedIterator for GenericIter<'a> {
} }
self.size -= 1; self.size -= 1;
let name = self.taglist.nth_tag_name(self.idx); let name = self.taglist.nth_tag_name(self.idx as u32);
Some((name, self.taglist.iter_tag_generic(name))) Some((name, self.taglist.iter_tag_generic(name)))
} }
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
let name = self.taglist.nth_tag_name(self.size as u32);
Some((name, self.taglist.iter_tag_generic(name)))
}
}
} }
impl<'a> ExactSizeIterator for GenericIter<'a> {} impl<'a> ExactSizeIterator for GenericIter<'a> {}
impl<'a> std::iter::FusedIterator for GenericIter<'a> {}
#[derive(Debug)] #[derive(Debug)]
pub struct Iter<'a> { pub struct Iter<'a> {
taglist: &'a TagListRef, taglist: &'a TagListRef,
idx: u32, idx: usize,
size: u32, size: usize,
} }
impl<'a> Iter<'a> { impl<'a> Iter<'a> {
@ -805,7 +909,7 @@ impl<'a> Iter<'a> {
Iter { Iter {
taglist, taglist,
idx: 0, idx: 0,
size: if size > 0 { size as u32 } else { 0 }, size: if size > 0 { size as usize } else { 0 },
} }
} }
} }
@ -818,7 +922,7 @@ impl<'a> Iterator for Iter<'a> {
return None; return None;
} }
let name = self.taglist.nth_tag_name(self.idx); let name = self.taglist.nth_tag_name(self.idx as u32);
let item = (name, self.taglist.generic(name).unwrap()); let item = (name, self.taglist.generic(name).unwrap());
self.idx += 1; self.idx += 1;
@ -826,14 +930,35 @@ impl<'a> Iterator for Iter<'a> {
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if self.idx == self.size { let remaining = self.size - self.idx;
return (0, Some(0));
}
let remaining = (self.size - self.idx) as usize;
(remaining, Some(remaining)) (remaining, Some(remaining))
} }
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
let name = self.taglist.nth_tag_name(end as u32);
Some((name, self.taglist.generic(name).unwrap()))
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
let name = self.taglist.nth_tag_name(self.size as u32 - 1);
Some((name, self.taglist.generic(name).unwrap()))
}
}
} }
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
@ -843,13 +968,27 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
} }
self.size -= 1; self.size -= 1;
let name = self.taglist.nth_tag_name(self.idx); let name = self.taglist.nth_tag_name(self.idx as u32);
Some((name, self.taglist.generic(name).unwrap())) Some((name, self.taglist.generic(name).unwrap()))
} }
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
let name = self.taglist.nth_tag_name(self.size as u32);
Some((name, self.taglist.generic(name).unwrap()))
}
}
} }
impl<'a> ExactSizeIterator for Iter<'a> {} impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> std::iter::FusedIterator for Iter<'a> {}
#[doc(alias = "gst_tag_exists")] #[doc(alias = "gst_tag_exists")]
pub fn tag_exists(name: &str) -> bool { pub fn tag_exists(name: &str) -> bool {
skip_assert_initialized!(); skip_assert_initialized!();