use core::cmp::{self, Ordering};
use core::hash::{Hash, Hasher};
use core::ops::{Bound, Index, IndexMut, Range, RangeBounds};
use std::fmt;
use std::iter::{repeat_with, Chain};
use std::mem::{self, ManuallyDrop};
use std::ptr;
use std::slice;
#[macro_use]
mod macros;
mod drain;
mod into_iter;
mod raw_vec;
pub use drain::Drain;
pub use into_iter::IntoIter;
use raw_vec::RawVec;
#[cfg(test)]
mod tests;
pub type Iter<'a, T> = Chain<slice::Iter<'a, T>, slice::Iter<'a, T>>;
pub type IterMut<'a, T> = Chain<slice::IterMut<'a, T>, slice::IterMut<'a, T>>;
struct Dropper<'a, T>(&'a mut [T]);
impl<'a, T> Drop for Dropper<'a, T> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(self.0);
}
}
}
pub struct AltDeque<T> {
tail: usize,
head: usize,
buf: RawVec<T>,
}
impl<T> AltDeque<T> {
pub fn new() -> Self {
Self::with_capacity(0)
}
pub fn with_capacity(capacity: usize) -> Self {
let buf = RawVec::with_capacity(capacity);
Self { tail: buf.capacity(), head: 0, buf }
}
#[inline]
pub fn capacity(&self) -> usize {
self.cap()
}
pub fn len(&self) -> usize {
self.cap() - self.tail + self.head
}
pub fn is_empty(&self) -> bool {
self.head == 0 && self.tail == self.cap()
}
pub fn as_slices(&self) -> (&[T], &[T]) {
unsafe {
let front = slice::from_raw_parts(self.buf_add(self.tail), self.cap() - self.tail);
let back = slice::from_raw_parts(self.buf.ptr(), self.head);
(front, back)
}
}
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
unsafe {
let front = slice::from_raw_parts_mut(self.buf_add(self.tail), self.cap() - self.tail);
let back = slice::from_raw_parts_mut(self.buf.ptr(), self.head);
(front, back)
}
}
pub fn get(&self, index: usize) -> Option<&T> {
let front_len = self.cap() - self.tail;
if index < front_len + self.head {
if index < front_len {
unsafe { Some(&*self.buf_add(self.tail + index)) }
} else {
unsafe { Some(&*self.buf_add(index - front_len)) }
}
} else {
None
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
let front_len = self.cap() - self.tail;
if index < front_len + self.head {
if index < front_len {
unsafe { Some(&mut *self.buf_add(self.tail + index)) }
} else {
unsafe { Some(&mut *self.buf_add(index - front_len)) }
}
} else {
None
}
}
pub fn reserve_exact(&mut self, additional: usize) {
let old_cap = self.cap();
let used_cap = self.len();
self.buf.reserve_exact(used_cap, additional);
unsafe {
self.handle_capacity_increase(old_cap);
}
}
pub fn reserve(&mut self, additional: usize) {
let old_cap = self.cap();
let used_cap = self.len();
self.buf.reserve(used_cap, additional);
unsafe {
self.handle_capacity_increase(old_cap);
}
}
pub fn resize_with<F>(&mut self, new_len: usize, generator: F)
where
F: FnMut() -> T,
{
let len = self.len();
if new_len > len {
self.extend(repeat_with(generator).take(new_len - len));
} else {
self.truncate(new_len);
}
}
pub fn shrink_to_fit(&mut self) {
self.shrink_to(0);
}
pub fn shrink_to(&mut self, min_capacity: usize) {
if min_capacity >= self.capacity() {
return;
}
let target_cap = cmp::max(min_capacity, self.len());
let front_len = self.cap() - self.tail;
let new_tail = target_cap - front_len;
unsafe {
self.copy(self.tail, new_tail, front_len);
}
self.tail = new_tail;
self.buf.shrink_to_fit(target_cap);
if self.cap() > target_cap {
let new_tail = self.cap() - front_len;
unsafe {
self.copy(self.tail, new_tail, front_len);
}
self.tail = new_tail;
}
}
pub fn truncate(&mut self, len: usize) {
struct DropGuard<T>{ ptr: *mut AltDeque<T>, old_tail: usize, len: usize }
impl<T> Drop for DropGuard<T> {
fn drop(&mut self) {
let deque = unsafe { self.ptr.as_mut().unwrap_unchecked() };
deque.tail = deque.cap() - self.len;
unsafe {
deque.copy(self.old_tail, deque.tail, self.len);
}
}
}
if len > self.len() {
return;
}
unsafe {
let (front, back) = self.as_mut_slices();
if len > front.len() {
let begin = len - front.len();
let drop_back = back.get_unchecked_mut(begin..) as *mut _;
self.head = begin;
ptr::drop_in_place(drop_back);
} else {
let drop_back = back as *mut _;
let drop_front = front.get_unchecked_mut(len..) as *mut _;
let _guard = DropGuard { ptr: self as *mut _, old_tail: self.tail, len};
self.head = 0;
self.tail = self.cap();
{
let _back_dropper = Dropper(&mut *drop_back);
ptr::drop_in_place(drop_front);
}
}
}
}
pub fn clear(&mut self) {
self.truncate(0);
}
pub fn contains(&self, x: &T) -> bool
where
T: PartialEq<T>,
{
let (a, b) = self.as_slices();
a.contains(x) || b.contains(x)
}
pub fn front(&self) -> Option<&T> {
if self.tail != self.cap() {
unsafe { Some(&*self.buf_add(self.tail)) }
} else if self.head != 0 {
unsafe { Some(&*self.buf_add(0)) }
} else {
None
}
}
pub fn front_mut(&mut self) -> Option<&mut T> {
if self.tail != self.cap() {
unsafe { Some(&mut *self.buf_add(self.tail)) }
} else if self.head != 0 {
unsafe { Some(&mut *self.buf_add(0)) }
} else {
None
}
}
pub fn back(&self) -> Option<&T> {
if self.head != 0 {
unsafe { Some(&*self.buf_add(self.head - 1)) }
} else if self.tail != self.cap() {
unsafe { Some(&*self.buf_add(self.cap() - 1)) }
} else {
None
}
}
pub fn back_mut(&mut self) -> Option<&mut T> {
if self.head != 0 {
unsafe { Some(&mut *self.buf_add(self.head - 1)) }
} else if self.tail != self.cap() {
unsafe { Some(&mut *self.buf_add(self.cap() - 1)) }
} else {
None
}
}
pub fn pop_front(&mut self) -> Option<T> {
if self.tail != self.cap() {
let tail = self.tail;
self.tail += 1;
unsafe { Some(ptr::read(self.buf_add(tail))) }
} else if self.head != 0 {
self.tail = self.cap() - self.head + 1;
unsafe {
self.copy(1, self.tail, self.head - 1);
}
self.head = 0;
unsafe { Some(ptr::read(self.buf_add(0))) }
} else {
None
}
}
pub fn pop_back(&mut self) -> Option<T> {
if self.head != 0 {
self.head -= 1;
unsafe { Some(ptr::read(self.buf_add(self.head))) }
} else if self.tail != self.cap() {
self.head = self.cap() - self.tail - 1;
unsafe {
self.copy(self.tail, 0, self.head);
}
self.tail = self.cap();
unsafe { Some(ptr::read(self.buf_add(self.cap() - 1))) }
} else {
None
}
}
pub fn push_front(&mut self, value: T) {
if self.is_full() {
self.grow();
}
self.tail -= 1;
unsafe {
ptr::write(self.buf_add(self.tail), value);
}
}
pub fn push_back(&mut self, value: T) {
if self.is_full() {
self.grow();
}
unsafe {
ptr::write(self.buf_add(self.head), value);
}
self.head += 1;
}
pub fn swap(&mut self, i: usize, j: usize) {
let front_len = self.cap() - self.tail;
let len = front_len + self.head;
let i = if i < front_len {
self.tail + i
} else if i < len{
i - front_len
} else {
index_out_of_bounds(len, i)
};
let j = if j < front_len {
self.tail + j
} else if j < len{
j - front_len
} else {
index_out_of_bounds(len, j)
};
unsafe {
ptr::swap(self.buf_add(i), self.buf_add(j));
}
}
pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
if index < self.len() {
self.swap(index, 0);
self.pop_front()
} else {
None
}
}
pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
let len = self.len();
if index < len {
self.swap(index, len - 1);
self.pop_back()
} else {
None
}
}
pub fn remove(&mut self, mut index: usize) -> Option<T> {
let front_len = self.cap() - self.tail;
if index < front_len {
let el = unsafe { ptr::read(self.buf_add(self.tail + index)) };
let new_tail = self.tail + 1;
unsafe {
self.copy(self.tail, new_tail, index);
}
self.tail = new_tail;
Some(el)
} else {
index -= front_len;
if index < self.head {
let el = unsafe { ptr::read(self.buf_add(index)) };
unsafe {
self.head -= 1;
self.copy(index + 1, index, self.head - index);
}
Some(el)
} else {
None
}
}
}
pub fn insert(&mut self, mut index: usize, value: T) {
if self.is_full() {
self.grow();
}
let front_len = self.cap() - self.tail;
if index < front_len {
unsafe {
let new_tail = self.tail - 1;
self.copy(self.tail, new_tail, index + 1);
self.tail = new_tail;
ptr::write(self.buf_add(self.tail + index), value);
}
} else {
index -= front_len;
if index <= self.head {
unsafe {
self.copy(index, index + 1, self.head - index);
self.head += 1;
ptr::write(self.buf_add(index), value);
}
} else {
index_out_of_bounds(self.len(), index + front_len);
}
}
}
#[must_use = "use `.truncate()` if you don't need the other half"]
pub fn split_off(&mut self, at: usize) -> Self {
let front_len = self.cap() - self.tail;
let len = front_len + self.head;
if at > len {
index_out_of_bounds(len, at);
}
let other_len = len - at;
let mut other = Self::with_capacity(other_len);
if at < front_len {
unsafe {
ptr::copy_nonoverlapping(self.buf_add(0), other.buf_add(other.cap() - self.head), self.head);
self.head = 0;
other.tail = other.cap() - other_len;
ptr::copy_nonoverlapping(self.buf_add(self.tail + at), other.buf_add(other.tail), front_len - at);
let new_tail = self.cap() - at;
ptr::copy(self.buf_add(self.tail), self.buf_add(new_tail), at);
self.tail = new_tail;
}
} else {
unsafe {
self.head = at - front_len;
other.tail = other.cap() - other_len;
ptr::copy_nonoverlapping(self.buf_add(self.head), other.buf_add(other.tail), other_len);
}
}
other
}
pub fn append(&mut self, other: &mut Self) {
let other_front_len = other.cap() - other.tail;
self.reserve(other_front_len + other.head);
unsafe {
ptr::copy_nonoverlapping(other.buf_add(other.tail), self.buf_add(self.head), other_front_len);
self.head += other_front_len;
ptr::copy_nonoverlapping(other.buf_add(0), self.buf_add(self.head), other.head);
self.head += other.head;
other.head = 0;
other.tail = other.cap();
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
self.retain_mut(|elem| f(elem));
}
pub fn retain_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut T) -> bool,
{
let len = self.len();
let mut cur = 0;
loop {
if cur == len {
return;
}
if !f(&mut self[cur]) {
cur += 1;
break;
}
cur += 1;
}
let mut idx = cur - 1; while cur < len {
if !f(&mut self[cur]) {
cur += 1;
continue;
}
self.swap(idx, cur);
cur += 1;
idx += 1;
}
self.truncate(idx);
}
pub fn make_contiguous(&mut self) -> &mut [T] {
if self.head == 0 {
return self.as_mut_slices().0;
}
let front_len = self.cap() - self.tail;
let free = self.tail - self.head;
if front_len == 0 {
unsafe {
self.copy(0, free, self.head);
}
} else if free >= self.head {
unsafe {
self.copy(self.tail, free, front_len);
ptr::copy_nonoverlapping(self.buf_add(0), self.buf_add(self.cap() - self.head), self.head);
}
} else if free >= front_len {
unsafe {
self.copy(0, front_len, self.head);
ptr::copy_nonoverlapping(self.buf_add(self.tail), self.buf_add(0), front_len);
self.copy(0, free, front_len + self.head);
}
} else {
let mut count = front_len + free;
let mut left = self.head.saturating_sub(count);
let mut right = self.head;
loop {
for i in left..right {
unsafe {
ptr::swap(self.buf_add(i), self.buf_add(i + count));
}
}
if left != 0 {
left = left.saturating_sub(count);
right -= count;
} else if right < count {
if right >= count - free {
unsafe {
self.copy(0, free, right - left);
}
break;
} else {
count -= right;
}
} else {
break;
}
}
}
self.head = 0;
self.tail = free;
self.as_mut_slices().0
}
pub fn rotate_left(&mut self, mut mid: usize) {
let front_len = self.cap() - self.tail;
if mid < front_len {
unsafe {
self.copy(self.tail, self.head, mid);
self.head += mid;
self.tail += mid;
}
} else {
mid -= front_len;
if mid <= self.head {
unsafe {
let count = self.head - mid;
self.head = mid;
self.tail -= count;
self.copy(mid, self.tail, count);
}
} else {
index_out_of_bounds(self.len(), mid + front_len);
}
}
}
pub fn rotate_right(&mut self, mut k: usize) {
if k <= self.head {
unsafe {
self.head -= k;
self.tail -= k;
self.copy(self.head, self.tail, k);
}
} else {
let front_len = self.cap() - self.tail;
k -= self.head;
if k <= front_len {
unsafe {
let count = front_len - k;
self.copy(self.tail, self.head, count);
self.head += count;
self.tail += count;
}
} else {
index_out_of_bounds(self.len(), k + self.head);
}
}
}
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
T: Ord,
{
self.binary_search_by(|e| e.cmp(x))
}
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a T) -> Ordering,
{
let (front, back) = self.as_slices();
let cmp_back = back.first().map(|elem| f(elem));
if let Some(Ordering::Equal) = cmp_back {
Ok(front.len())
} else if let Some(Ordering::Less) = cmp_back {
back.binary_search_by(f).map(|idx| idx + front.len()).map_err(|idx| idx + front.len())
} else {
front.binary_search_by(f)
}
}
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a T) -> B,
B: Ord,
{
self.binary_search_by(|k| f(k).cmp(b))
}
pub fn partition_point<P>(&self, mut pred: P) -> usize
where
P: FnMut(&T) -> bool,
{
let (front, back) = self.as_slices();
if let Some(true) = back.first().map(|v| pred(v)) {
back.partition_point(pred) + front.len()
} else {
front.partition_point(pred)
}
}
pub fn iter(&self) -> Iter<'_, T> {
let (front, back) = self.as_slices();
front.iter().chain(back.iter())
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
let (front, back) = self.as_mut_slices();
front.iter_mut().chain(back.iter_mut())
}
pub fn range<R>(&self, range: R) -> Iter<'_, T>
where
R: RangeBounds<usize>,
{
let Range { start, end } = simplify_range(range, self.len());
let (front, back) = self.as_slices();
let front_len = front.len();
if start >= front_len {
back[start - front_len..end - front_len].iter().chain(front[..0].iter())
} else if end <= front_len {
front[start..end].iter().chain(back[..0].iter())
} else {
front[start..].iter().chain(back[..end - front_len].iter())
}
}
pub fn range_mut<R>(&mut self, range: R) -> IterMut<'_, T>
where
R: RangeBounds<usize>,
{
let Range { start, end } = simplify_range(range, self.len());
let (front, back) = self.as_mut_slices();
let front_len = front.len();
if start >= front_len {
back[start - front_len..end - front_len].iter_mut().chain(front[..0].iter_mut())
} else if end <= front_len {
front[start..end].iter_mut().chain(back[..0].iter_mut())
} else {
front[start..].iter_mut().chain(back[..end - front_len].iter_mut())
}
}
pub fn drain<R>(&mut self, range: R) -> Drain<T>
where
R: RangeBounds<usize>,
{
let range = simplify_range(range, self.len());
let old_head = self.head;
let old_tail = self.tail;
self.head = 0;
self.tail = self.cap();
Drain::new(self, old_head, old_tail, range)
}
#[inline]
fn cap(&self) -> usize {
self.buf.capacity()
}
#[inline]
fn is_full(&self) -> bool {
self.tail == self.head
}
#[inline]
unsafe fn buf_add(&self, offset: usize) -> *mut T {
self.buf.ptr().add(offset)
}
#[inline]
unsafe fn copy(&mut self, from: usize, to: usize, len: usize) {
ptr::copy(self.buf_add(from), self.buf_add(to), len);
}
#[inline(never)]
fn grow(&mut self) {
debug_assert!(self.is_full());
let old_cap = self.cap();
self.buf.reserve_for_push(old_cap);
unsafe { self.handle_capacity_increase(old_cap); }
debug_assert!(!self.is_full());
}
unsafe fn handle_capacity_increase(&mut self, old_cap: usize) {
debug_assert!(old_cap >= self.tail);
debug_assert!(old_cap <= self.cap());
if old_cap == self.cap() {
return;
}
let growth = self.cap() - old_cap;
let front_len = old_cap - self.tail;
let new_tail = self.tail + growth;
if growth >= front_len {
unsafe {
ptr::copy_nonoverlapping(self.buf_add(self.tail), self.buf_add(new_tail), front_len);
}
} else {
unsafe {
ptr::copy(self.buf_add(self.tail), self.buf_add(new_tail), front_len);
}
}
self.tail = new_tail;
}
}
impl<T: Clone> AltDeque<T> {
pub fn resize(&mut self, new_len: usize, value: T) {
self.resize_with(new_len, || value.clone());
}
}
impl<T: Clone> Clone for AltDeque<T> {
fn clone(&self) -> Self {
let mut deque = Self::with_capacity(self.len());
if mem::size_of::<T>() == 0 {
deque.tail = deque.cap() - self.len();
} else {
for el in self.iter() {
deque.push_back(el.clone());
}
}
deque
}
}
impl<T: fmt::Debug> fmt::Debug for AltDeque<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self).finish()
}
}
impl<T> Default for AltDeque<T> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T> Drop for AltDeque<T> {
fn drop(&mut self) {
let (front, back) = self.as_mut_slices();
unsafe {
let _back_dropper = Dropper(back);
ptr::drop_in_place(front);
}
}
}
impl<T> Extend<T> for AltDeque<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let mut iter = iter.into_iter();
while let Some(element) = iter.next() {
if self.is_full() {
let (lower, _) = iter.size_hint();
self.reserve(lower.max(1));
}
let head = self.head;
self.head += 1;
unsafe {
ptr::write(self.buf_add(head), element);
}
}
}
}
impl<'a, T: 'a + Copy> Extend<&'a T> for AltDeque<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied());
}
}
impl<T> From<Vec<T>> for AltDeque<T> {
fn from(other: Vec<T>) -> Self {
unsafe {
let mut other = ManuallyDrop::new(other);
let (other_buf, len, capacity) = (other.as_mut_ptr(), other.len(), other.capacity());
let buf = RawVec::from_raw_parts(other_buf, capacity);
Self { buf, head: len, tail: capacity }
}
}
}
impl<T> From<AltDeque<T>> for Vec<T> {
fn from(mut other: AltDeque<T>) -> Self {
if other.tail != other.cap() {
other.make_contiguous();
unsafe {
other.copy(other.tail, 0, other.cap() - other.tail);
}
}
unsafe {
let other = ManuallyDrop::new(other);
let buf = other.buf.ptr();
let len = other.len();
let cap = other.cap();
Vec::from_raw_parts(buf, len, cap)
}
}
}
impl<T, const N: usize> From<[T; N]> for AltDeque<T> {
fn from(arr: [T; N]) -> Self {
let mut deque = AltDeque::with_capacity(N);
let arr = ManuallyDrop::new(arr);
deque.tail = deque.cap() - N;
if mem::size_of::<T>() != 0 {
unsafe {
ptr::copy_nonoverlapping(arr.as_ptr(), deque.buf_add(deque.tail), N);
}
}
deque
}
}
impl<T, const N: usize, const M: usize> From<([T; N], [T; M])> for AltDeque<T> {
fn from(tuple: ([T; N], [T; M])) -> Self {
let (front, back) = tuple;
let mut deque = AltDeque::with_capacity(N + M);
if mem::size_of::<T>() != 0 {
let front = ManuallyDrop::new(front);
let back = ManuallyDrop::new(back);
deque.tail = deque.cap() - N;
deque.head = M;
unsafe {
debug_assert!(deque.head <= deque.tail);
ptr::copy_nonoverlapping(front.as_ptr(), deque.buf_add(deque.tail), N);
ptr::copy_nonoverlapping(back.as_ptr(), deque.buf_add(0), M);
}
}
deque
}
}
impl<T> FromIterator<T> for AltDeque<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let iter = iter.into_iter();
let (lower, _) = iter.size_hint();
let mut deque = Self::with_capacity(lower);
deque.extend(iter);
deque
}
}
impl<T: Hash> Hash for AltDeque<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(self.len());
self.iter().for_each(|elem| elem.hash(state));
}
}
impl<T> Index<usize> for AltDeque<T> {
type Output = T;
#[inline]
fn index(&self, index: usize) -> &T {
self.get(index).unwrap_or_else(|| index_out_of_bounds(self.len(), index))
}
}
impl<T> IndexMut<usize> for AltDeque<T> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
let len = self.len();
self.get_mut(index).unwrap_or_else(|| index_out_of_bounds(len, index))
}
}
impl<T> IntoIterator for AltDeque<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter::new(self)
}
}
impl<'a, T> IntoIterator for &'a AltDeque<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut AltDeque<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
impl<T: PartialOrd> PartialOrd for AltDeque<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl<T: Ord> Ord for AltDeque<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl<T: PartialEq> PartialEq for AltDeque<T> {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
let (sa, sb) = self.as_slices();
let (oa, ob) = other.as_slices();
if sa.len() == oa.len() {
sa == oa && sb == ob
} else if sa.len() < oa.len() {
let front = sa.len();
let mid = oa.len() - front;
let (oa_front, oa_mid) = oa.split_at(front);
let (sb_mid, sb_back) = sb.split_at(mid);
sa == oa_front && sb_mid == oa_mid && sb_back == ob
} else {
let front = oa.len();
let mid = sa.len() - front;
let (sa_front, sa_mid) = sa.split_at(front);
let (ob_mid, ob_back) = ob.split_at(mid);
sa_front == oa && sa_mid == ob_mid && sb == ob_back
}
}
}
impl<T: Eq> Eq for AltDeque<T> {}
__impl_slice_eq! { [] AltDeque<T>, Vec<U>, }
__impl_slice_eq! { [] AltDeque<T>, &[U], }
__impl_slice_eq! { [] AltDeque<T>, &mut [U], }
__impl_slice_eq! { [const N: usize] AltDeque<T>, [U; N], }
__impl_slice_eq! { [const N: usize] AltDeque<T>, &[U; N], }
__impl_slice_eq! { [const N: usize] AltDeque<T>, &mut [U; N], }
fn index_out_of_bounds(len: usize, index: usize) -> ! {
panic!("index out of bounds: the len is {} but the index is {}", len, index);
}
fn simplify_range(range: impl RangeBounds<usize>, len: usize) -> Range<usize> {
let start = match range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&i) => i,
Bound::Excluded(&i) => i.checked_add(1).expect("range start Bound::Excluded(usize::MAX) is > usize::MAX"),
};
let end = match range.end_bound() {
Bound::Unbounded => len,
Bound::Excluded(&i) if i <= len => i,
Bound::Included(&i) if i < len => i + 1,
bound => panic!("range end {:?} should be <= length {}", bound, len),
};
if start > end {
panic!(
"range start {:?} should be <= range end {:?}",
range.start_bound(),
range.end_bound()
);
}
start..end
}