move index code around

This commit is contained in:
Maybe Waffle 2023-04-19 11:06:46 +00:00
parent e496fbec92
commit 99ebfe2f15
2 changed files with 100 additions and 99 deletions

View File

@ -5,7 +5,7 @@
slice,
};
use crate::{idx::Idx, vec::IndexVec};
use crate::{Idx, IndexVec};
/// A view into contiguous `T`s, indexed by `I` rather than by `usize`.
///
@ -140,6 +140,17 @@ pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) {
let ptr = self.raw.as_mut_ptr();
unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) }
}
#[inline]
pub fn binary_search(&self, value: &T) -> Result<I, I>
where
T: Ord,
{
match self.raw.binary_search(value) {
Ok(i) => Ok(Idx::new(i)),
Err(i) => Err(Idx::new(i)),
}
}
}
impl<I: Idx, J: Idx> IndexSlice<I, J> {
@ -172,20 +183,6 @@ pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> {
}
}
impl<I: Idx, T: Ord> IndexSlice<I, T> {
#[inline]
pub fn binary_search(&self, value: &T) -> Result<I, I> {
match self.raw.binary_search(value) {
Ok(i) => Ok(Idx::new(i)),
Err(i) => Err(Idx::new(i)),
}
}
}
// Whether `IndexSlice` is `Send` depends only on the data,
// not the phantom data.
unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
@ -208,6 +205,26 @@ fn index_mut(&mut self, index: I) -> &mut T {
}
}
impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> slice::Iter<'a, T> {
self.raw.iter()
}
}
impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> slice::IterMut<'a, T> {
self.raw.iter_mut()
}
}
impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
type Owned = IndexVec<I, T>;
@ -234,22 +251,6 @@ fn default() -> Self {
}
}
impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> slice::Iter<'a, T> {
self.raw.iter()
}
}
impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> slice::IterMut<'a, T> {
self.raw.iter_mut()
}
}
// Whether `IndexSlice` is `Send` depends only on the data,
// not the phantom data.
unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}

View File

@ -9,8 +9,7 @@
use std::slice;
use std::vec;
use crate::idx::Idx;
use crate::slice::IndexSlice;
use crate::{Idx, IndexSlice};
/// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`.
///
@ -25,30 +24,6 @@ pub struct IndexVec<I: Idx, T> {
_marker: PhantomData<fn(&I)>,
}
// Whether `IndexVec` is `Send` depends only on the data,
// not the phantom data.
unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {}
#[cfg(feature = "rustc_serialize")]
impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> {
fn encode(&self, s: &mut S) {
Encodable::encode(&self.raw, s);
}
}
#[cfg(feature = "rustc_serialize")]
impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
fn decode(d: &mut D) -> Self {
IndexVec { raw: Decodable::decode(d), _marker: PhantomData }
}
}
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
}
}
impl<I: Idx, T> IndexVec<I, T> {
#[inline]
pub fn new() -> Self {
@ -183,6 +158,14 @@ pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -
&mut self[elem]
}
#[inline]
pub fn resize(&mut self, new_len: usize, value: T)
where
T: Clone,
{
self.raw.resize(new_len, value)
}
#[inline]
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
let min_new_len = elem.index() + 1;
@ -190,6 +173,30 @@ pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
}
}
/// `IndexVec` is often used as a map, so it provides some map-like APIs.
impl<I: Idx, T> IndexVec<I, Option<T>> {
#[inline]
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
self.ensure_contains_elem(index, || None).replace(value)
}
#[inline]
pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
self.ensure_contains_elem(index, || None).get_or_insert_with(value)
}
#[inline]
pub fn remove(&mut self, index: I) -> Option<T> {
self.get_mut(index)?.take()
}
}
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
}
}
impl<I: Idx, T> Deref for IndexVec<I, T> {
type Target = IndexSlice<I, T>;
@ -218,38 +225,6 @@ fn borrow_mut(&mut self) -> &mut IndexSlice<I, T> {
}
}
/// `IndexVec` is often used as a map, so it provides some map-like APIs.
impl<I: Idx, T> IndexVec<I, Option<T>> {
#[inline]
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
self.ensure_contains_elem(index, || None).replace(value)
}
#[inline]
pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
self.ensure_contains_elem(index, || None).get_or_insert_with(value)
}
#[inline]
pub fn remove(&mut self, index: I) -> Option<T> {
self.get_mut(index)?.take()
}
}
impl<I: Idx, T: Clone> IndexVec<I, T> {
#[inline]
pub fn resize(&mut self, new_len: usize, value: T) {
self.raw.resize(new_len, value)
}
}
impl<I: Idx, T> Default for IndexVec<I, T> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<I: Idx, T> Extend<T> for IndexVec<I, T> {
#[inline]
fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) {
@ -279,13 +254,6 @@ fn from_iter<J>(iter: J) -> Self
}
}
impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> {
#[inline]
fn from(array: [T; N]) -> Self {
IndexVec::from_raw(array.into())
}
}
impl<I: Idx, T> IntoIterator for IndexVec<I, T> {
type Item = T;
type IntoIter = vec::IntoIter<T>;
@ -316,5 +284,37 @@ fn into_iter(self) -> slice::IterMut<'a, T> {
}
}
impl<I: Idx, T> Default for IndexVec<I, T> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> {
#[inline]
fn from(array: [T; N]) -> Self {
IndexVec::from_raw(array.into())
}
}
#[cfg(feature = "rustc_serialize")]
impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> {
fn encode(&self, s: &mut S) {
Encodable::encode(&self.raw, s);
}
}
#[cfg(feature = "rustc_serialize")]
impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
fn decode(d: &mut D) -> Self {
IndexVec { raw: Decodable::decode(d), _marker: PhantomData }
}
}
// Whether `IndexVec` is `Send` depends only on the data,
// not the phantom data.
unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {}
#[cfg(test)]
mod tests;