Lift getting the length of the array out.
This changes get() to return an Option<> and adds a get_unchecked() that doesn't do a bounds check. This means our bounds check can be inlined into the caller instead of us having to CFArrayGetCount twice for each element.
This commit is contained in:
@@ -70,16 +70,17 @@ impl<T> Drop for CFArray<T> {
|
||||
pub struct CFArrayIterator<'a, T: 'a> {
|
||||
array: &'a CFArray<T>,
|
||||
index: CFIndex,
|
||||
len: CFIndex,
|
||||
}
|
||||
|
||||
impl<'a, T: FromVoid> Iterator for CFArrayIterator<'a, T> {
|
||||
type Item = ItemRef<'a, T>;
|
||||
|
||||
fn next(&mut self) -> Option<ItemRef<'a, T>> {
|
||||
if self.index >= self.array.len() {
|
||||
if self.index >= self.len {
|
||||
None
|
||||
} else {
|
||||
let value = self.array.get(self.index);
|
||||
let value = unsafe { self.array.get_unchecked(self.index) };
|
||||
self.index += 1;
|
||||
Some(value)
|
||||
}
|
||||
@@ -131,7 +132,8 @@ impl<T> CFArray<T> {
|
||||
pub fn iter<'a>(&'a self) -> CFArrayIterator<'a, T> {
|
||||
CFArrayIterator {
|
||||
array: self,
|
||||
index: 0
|
||||
index: 0,
|
||||
len: self.len(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,9 +145,17 @@ impl<T> CFArray<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get<'a>(&'a self, index: CFIndex) -> ItemRef<'a, T> where T: FromVoid {
|
||||
assert!(index < self.len());
|
||||
unsafe { T::from_void(CFArrayGetValueAtIndex(self.0, index)) }
|
||||
pub unsafe fn get_unchecked<'a>(&'a self, index: CFIndex) -> ItemRef<'a, T> where T: FromVoid {
|
||||
T::from_void(CFArrayGetValueAtIndex(self.0, index))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get<'a>(&'a self, index: CFIndex) -> Option<ItemRef<'a, T>> where T: FromVoid {
|
||||
if index < self.len() {
|
||||
Some(unsafe { T::from_void(CFArrayGetValueAtIndex(self.0, index)) } )
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_values(&self, range: CFRange) -> Vec<*const c_void> {
|
||||
@@ -216,11 +226,11 @@ mod tests {
|
||||
{
|
||||
let arr: CFArray<CFString> = CFArray::from_CFTypes(&[string]);
|
||||
{
|
||||
let p = arr.get(0);
|
||||
let p = arr.get(0).unwrap();
|
||||
assert_eq!(p.retain_count(), 1);
|
||||
}
|
||||
{
|
||||
x = arr.get(0).clone();
|
||||
x = arr.get(0).unwrap().clone();
|
||||
assert_eq!(x.retain_count(), 2);
|
||||
assert_eq!(x.to_string(), "bar");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user