Skip to content

Commit b7cdd93

Browse files
committed
Auto merge of rust-lang#14747 - oxalica:feat/arena-idx-range, r=HKalbasi
More APIs for `la_arena::IdxRange` ```rust impl<T> ExactSizeIterator for IdxRange<T>; impl<T> Arena<T> { pub fn alloc_many<II: IntoIterator<Item = T>>(&mut self, iter: II) -> IdxRange<T>; } ``` 1. There are no currently ways to get `IdxRange` without manually offseting `Idx`. Providing a method for multiple-allocation simplifies this process and makes it less error-prone. 2. `IdxRange: ExactSizeIterator` makes `iter.zip(range).rev()` possible. Since `Zip: DoubleEndedIterator` requires all its arguments to be `ExactSizeIterator`. It also ease the usage for, eg. `len()`. 3. Fixed a typo. I noticed that `IdxRange::end` may be invalid. Is it good to return `Idx` instead of `RawIdx`?
2 parents c26a43d + add94d3 commit b7cdd93

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

lib/la-arena/src/lib.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use std::{
77
cmp, fmt,
88
hash::{Hash, Hasher},
9-
iter::Enumerate,
9+
iter::{Enumerate, FusedIterator},
1010
marker::PhantomData,
1111
ops::{Index, IndexMut, Range, RangeInclusive},
1212
};
@@ -168,17 +168,40 @@ impl<T> IdxRange<T> {
168168
Idx::from_raw(RawIdx::from(self.range.start))
169169
}
170170

171-
/// Returns the start of the index range.
171+
/// Returns the end of the index range.
172172
pub fn end(&self) -> Idx<T> {
173173
Idx::from_raw(RawIdx::from(self.range.end))
174174
}
175175
}
176176

177177
impl<T> Iterator for IdxRange<T> {
178178
type Item = Idx<T>;
179+
179180
fn next(&mut self) -> Option<Self::Item> {
180181
self.range.next().map(|raw| Idx::from_raw(raw.into()))
181182
}
183+
184+
fn size_hint(&self) -> (usize, Option<usize>) {
185+
self.range.size_hint()
186+
}
187+
188+
fn count(self) -> usize
189+
where
190+
Self: Sized,
191+
{
192+
self.range.count()
193+
}
194+
195+
fn last(self) -> Option<Self::Item>
196+
where
197+
Self: Sized,
198+
{
199+
self.range.last().map(|raw| Idx::from_raw(raw.into()))
200+
}
201+
202+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
203+
self.range.nth(n).map(|raw| Idx::from_raw(raw.into()))
204+
}
182205
}
183206

184207
impl<T> DoubleEndedIterator for IdxRange<T> {
@@ -187,6 +210,10 @@ impl<T> DoubleEndedIterator for IdxRange<T> {
187210
}
188211
}
189212

213+
impl<T> ExactSizeIterator for IdxRange<T> {}
214+
215+
impl<T> FusedIterator for IdxRange<T> {}
216+
190217
impl<T> fmt::Debug for IdxRange<T> {
191218
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192219
f.debug_tuple(&format!("IdxRange::<{}>", std::any::type_name::<T>()))
@@ -305,6 +332,21 @@ impl<T> Arena<T> {
305332
idx
306333
}
307334

335+
/// Densely allocates multiple values, returning the values’ index range.
336+
///
337+
/// ```
338+
/// let mut arena = la_arena::Arena::new();
339+
/// let range = arena.alloc_many(0..4);
340+
///
341+
/// assert_eq!(arena[range], [0, 1, 2, 3]);
342+
/// ```
343+
pub fn alloc_many<II: IntoIterator<Item = T>>(&mut self, iter: II) -> IdxRange<T> {
344+
let start = self.next_idx();
345+
self.extend(iter);
346+
let end = self.next_idx();
347+
IdxRange::new(start..end)
348+
}
349+
308350
/// Returns an iterator over the arena’s elements.
309351
///
310352
/// ```

0 commit comments

Comments
 (0)