1use std::{slice as stdslice, mem};
3use base::{u4lo, u4};
4use pair::u4x2;
5use slice::{self, NibSliceAligned, NibSliceAlignedMut, NibSliceFull, NibSliceNoR};
6use common::{get_nib, set_nib, shift_left, shift_right};
7
8#[derive(Clone)]
10pub struct NibVec {
11 inner: Vec<u4x2>,
12 has_right_lo: bool,
13}
14impl NibVec {
15 pub fn new() -> Self {
17 NibVec { inner: Vec::new(), has_right_lo: true }
18 }
19
20 pub fn from_pair_vec(inner: Vec<u4x2>) -> Self {
22 NibVec { inner, has_right_lo: true }
23 }
24
25 pub fn from_byte_vec(inner: Vec<u8>) -> Self {
27 Self::from_pair_vec(unsafe { mem::transmute(inner) })
28 }
29
30 pub fn len(&self) -> usize {
32 (self.inner.len() >> 1).saturating_sub(!self.has_right_lo as usize)
33 }
34
35 pub fn is_empty(&self) -> bool {
37 self.inner.is_empty()
38 }
39
40 pub fn capacity(&self) -> usize {
42 self.inner.capacity() >> 1
43 }
44
45 pub fn push<T: u4>(&mut self, nib: T) {
51 self.has_right_lo = !self.has_right_lo;
52 if self.has_right_lo {
53 self.inner.push(u4x2::from_hi(nib.to_u4hi()));
54 } else {
55 let i = self.inner.len() - 1;
56 self.inner[i].set_lo(nib);
57 }
58 }
59
60 pub fn insert<T: u4>(&mut self, index: usize, nib: T) {
62 if self.has_right_lo {
63 self.push(u4lo::from_lo(0));
64 }
65 shift_right(self.inner.as_mut_slice(), index);
66 set_nib(self.inner.as_mut_slice(), index, nib);
67 }
68
69 fn discard_at(&mut self, index: usize) {
70 shift_left(self.inner.as_mut_slice(), index);
71 self.has_right_lo = !self.has_right_lo;
72 if self.has_right_lo {
73 self.inner.pop();
74 }
75 }
76
77 pub fn remove<T: u4>(&mut self, index: usize) -> T {
79 let ret = get_nib(self.inner.as_slice(), index);
80 self.discard_at(index);
81 ret
82 }
83
84 pub fn pop<T: u4>(&mut self) -> Option<T> {
86 self.has_right_lo = !self.has_right_lo;
87 if self.has_right_lo {
88 Some(T::from_lo(self.inner[self.inner.len() - 1].lo().to_lo()))
89 } else {
90 self.inner.pop().map(|pair| T::from_hi(pair.hi().to_hi()))
91 }
92 }
93
94 pub fn clear(&mut self) {
96 self.inner.clear();
97 self.has_right_lo = true;
98 }
99
100 pub fn as_slice(&self) -> NibSliceAligned {
102 if self.has_right_lo {
103 NibSliceAligned::Even(unsafe { &*(&self.inner[..] as *const [u4x2] as *const NibSliceFull) })
104 } else {
105 NibSliceAligned::Odd(unsafe { &*(&self.inner[..] as *const [u4x2] as *const NibSliceNoR) })
106 }
107 }
108
109 pub fn as_mut_slice(&mut self) -> NibSliceAlignedMut {
111 if self.has_right_lo {
112 NibSliceAlignedMut::Even(unsafe { &mut *(&mut self.inner[..] as *mut [u4x2] as *mut NibSliceFull) })
113 } else {
114 NibSliceAlignedMut::Odd(unsafe { &mut *(&mut self.inner[..] as *mut [u4x2] as *mut NibSliceNoR) })
115 }
116 }
117}
118impl Default for NibVec {
119 fn default() -> Self {
120 NibVec::new()
121 }
122}
123impl slice::private::Sealed for NibVec {
124 #[inline(always)]
125 fn has_left_hi(&self) -> bool { true }
126 #[inline(always)]
127 fn has_right_lo(&self) -> bool { self.as_slice().has_right_lo() }
128 #[inline(always)]
129 fn iter(&self) -> stdslice::Iter<u4x2> { self.inner.iter() }
130}
131impl slice::private::SealedMut for NibVec {
132 #[inline(always)]
133 fn iter_mut(&mut self) -> stdslice::IterMut<u4x2> { self.inner.iter_mut() }
134}
135impl slice::NibSliceExt for NibVec {}
136impl slice::NibSliceMutExt for NibVec {}