compressed_intvec/seq/slice.rs
1//! Zero-copy slices of a [`SeqVec`].
2//!
3//! This module provides [`SeqVecSlice`], a view into a contiguous portion of a
4//! [`SeqVec`]. Slices are immutable and do not own their data; they borrow it
5//! from the parent [`SeqVec`].
6//!
7//! [`SeqVec`]: crate::seq::SeqVec
8
9use super::{iter::SeqVecBitReader, SeqIter, SeqVec};
10use crate::variable::traits::Storable;
11use dsi_bitstream::prelude::{BitRead, BitSeek, CodesRead, Endianness};
12use std::cmp::Ordering;
13use std::fmt;
14use std::ops::Range;
15
16/// An immutable, zero-copy slice of a [`SeqVec`].
17///
18/// This struct provides a view into a contiguous portion of a [`SeqVec`]
19/// without copying the underlying compressed data. It is created by the
20/// [`slice`] or [`split_at`] methods on a [`SeqVec`].
21///
22/// All operations on a [`SeqVecSlice`] are relative to the start of the slice,
23/// not the parent vector. The slice contains a contiguous range of sequences.
24///
25/// [`SeqVec`]: super::SeqVec
26/// [`slice`]: super::SeqVec::slice
27/// [`split_at`]: super::SeqVec::split_at
28///
29/// # Examples
30///
31/// ```
32/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
33/// use compressed_intvec::seq::{SeqVec, LESeqVec};
34///
35/// let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6], &[7, 8, 9, 10]];
36/// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
37///
38/// // Create a slice of sequences 1 through 2 (indices 1 and 2)
39/// let slice = vec.slice(1, 2).unwrap();
40///
41/// assert_eq!(slice.len(), 2);
42///
43/// // Accessing a sequence within the slice
44/// // Index 0 of the slice corresponds to sequence 1 of the original vector
45/// let seq0: Vec<u32> = slice.get(0).unwrap().collect();
46/// assert_eq!(seq0, vec![3, 4, 5]);
47///
48/// // Iterating over the slice
49/// let all_values: Vec<Vec<u32>> = slice.iter()
50/// .map(|seq| seq.collect())
51/// .collect();
52/// assert_eq!(all_values, vec![vec![3, 4, 5], vec![6]]);
53/// # Ok(())
54/// # }
55/// ```
56#[derive(Debug, Clone)]
57pub struct SeqVecSlice<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> {
58 /// A reference to the parent vector.
59 vec: &'a SeqVec<T, E, B>,
60 /// The starting sequence index within the parent vector.
61 start: usize,
62 /// The number of sequences in the slice.
63 len: usize,
64}
65
66impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecSlice<'a, T, E, B> {
67 /// Creates a new [`SeqVecSlice`].
68 pub(super) fn new(vec: &'a SeqVec<T, E, B>, range: Range<usize>) -> Self {
69 debug_assert!(
70 range.end <= vec.num_sequences(),
71 "Slice range exceeds vector bounds"
72 );
73 Self {
74 vec,
75 start: range.start,
76 len: range.len(),
77 }
78 }
79
80 /// Returns the number of sequences in the slice.
81 #[inline]
82 pub fn len(&self) -> usize {
83 self.len
84 }
85
86 /// Returns `true` if the slice contains no sequences.
87 #[inline]
88 pub fn is_empty(&self) -> bool {
89 self.len == 0
90 }
91
92 /// Returns an iterator over the elements of the sequence at `index` within
93 /// the slice, or `None` if the index is out of bounds.
94 ///
95 /// The index is relative to the start of the slice.
96 #[inline]
97 pub fn get(&self, index: usize) -> Option<SeqIter<'_, T, E>>
98 where
99 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
100 + CodesRead<E>
101 + BitSeek<Error = core::convert::Infallible>,
102 {
103 if index >= self.len {
104 return None;
105 }
106 // SAFETY: The bounds check above ensures `index` is valid.
107 Some(unsafe { self.get_unchecked(index) })
108 }
109
110 /// Returns an iterator over the elements of the sequence at `index` within
111 /// the slice without bounds checking.
112 ///
113 /// The index is relative to the start of the slice.
114 ///
115 /// # Safety
116 ///
117 /// Calling this method with an out-of-bounds index is undefined behavior.
118 /// The caller must ensure that `index < self.len()`.
119 #[inline(always)]
120 pub unsafe fn get_unchecked(&self, index: usize) -> SeqIter<'_, T, E>
121 where
122 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
123 + CodesRead<E>
124 + BitSeek<Error = core::convert::Infallible>,
125 {
126 debug_assert!(index < self.len, "Index out of bounds");
127 // Translate slice-relative index to parent vector index.
128 let parent_index = self.start + index;
129 unsafe { self.vec.get_unchecked(parent_index) }
130 }
131
132 /// Returns the sequence at `index` as a materialized `Vec<T>`, or `None`
133 /// if the index is out of bounds.
134 ///
135 /// This method fully decodes the sequence and allocates a new vector.
136 ///
137 /// # Examples
138 ///
139 /// ```
140 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
141 /// use compressed_intvec::seq::{SeqVec, LESeqVec};
142 ///
143 /// let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6]];
144 /// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
145 ///
146 /// let slice = vec.slice(1, 2).unwrap();
147 /// assert_eq!(slice.decode_vec(0), Some(vec![3, 4, 5]));
148 /// assert_eq!(slice.decode_vec(1), Some(vec![6]));
149 /// assert_eq!(slice.decode_vec(2), None); // Out of bounds
150 /// # Ok(())
151 /// # }
152 /// ```
153 #[inline]
154 pub fn decode_vec(&self, index: usize) -> Option<Vec<T>>
155 where
156 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
157 + CodesRead<E>
158 + BitSeek<Error = core::convert::Infallible>,
159 {
160 let parent_index = self.start.checked_add(index)?;
161 if index >= self.len {
162 return None;
163 }
164 self.vec.decode_vec(parent_index)
165 }
166
167 /// Returns the sequence at `index` as a materialized `Vec<T>` without bounds
168 /// checking.
169 ///
170 /// # Safety
171 ///
172 /// Calling this method with an out-of-bounds index is undefined behavior.
173 #[inline]
174 pub unsafe fn decode_vec_unchecked(&self, index: usize) -> Vec<T>
175 where
176 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
177 + CodesRead<E>
178 + BitSeek<Error = core::convert::Infallible>,
179 {
180 let parent_index = self.start + index;
181 unsafe { self.vec.decode_vec_unchecked(parent_index) }
182 }
183
184 /// Decodes the sequence at `index` into a reusable buffer.
185 ///
186 /// The buffer is cleared and then filled with the decoded sequence elements.
187 /// Returns the number of elements decoded, or `None` if the index is out
188 /// of bounds.
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
194 /// use compressed_intvec::seq::{SeqVec, LESeqVec};
195 ///
196 /// let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6]];
197 /// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
198 ///
199 /// let slice = vec.slice(1, 2).unwrap();
200 ///
201 /// let mut buf = Vec::new();
202 /// assert_eq!(slice.decode_into(0, &mut buf), Some(3));
203 /// assert_eq!(buf, vec![3, 4, 5]);
204 ///
205 /// // Buffer is reused (cleared internally).
206 /// assert_eq!(slice.decode_into(1, &mut buf), Some(1));
207 /// assert_eq!(buf, vec![6]);
208 /// # Ok(())
209 /// # }
210 /// ```
211 #[inline]
212 pub fn decode_into(&self, index: usize, buf: &mut Vec<T>) -> Option<usize>
213 where
214 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
215 + CodesRead<E>
216 + BitSeek<Error = core::convert::Infallible>,
217 {
218 let parent_index = self.start.checked_add(index)?;
219 if index >= self.len {
220 return None;
221 }
222 self.vec.decode_into(parent_index, buf)
223 }
224
225 /// Decodes sequence `index` into the provided buffer without bounds checking.
226 ///
227 /// # Safety
228 ///
229 /// Calling this method with an out-of-bounds index is undefined behavior.
230 #[inline]
231 pub unsafe fn decode_into_unchecked(&self, index: usize, buf: &mut Vec<T>) -> usize
232 where
233 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
234 + CodesRead<E>
235 + BitSeek<Error = core::convert::Infallible>,
236 {
237 let parent_index = self.start + index;
238 unsafe { self.vec.decode_into_unchecked(parent_index, buf) }
239 }
240
241 /// Returns an iterator over the sequences in the slice.
242 pub fn iter(&self) -> SeqVecSliceIter<'_, T, E, B>
243 where
244 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
245 + CodesRead<E>
246 + BitSeek<Error = core::convert::Infallible>,
247 {
248 SeqVecSliceIter::new(self)
249 }
250}
251
252impl<T, E, B> SeqVecSlice<'_, T, E, B>
253where
254 T: Storable + PartialEq,
255 E: Endianness,
256 B: AsRef<[u64]>,
257 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
258 + CodesRead<E>
259 + BitSeek<Error = core::convert::Infallible>,
260{
261 /// Binary searches this slice for a sequence matching the given elements.
262 ///
263 /// If the sequence is found, returns `Ok(usize)` with the index of the
264 /// matching sequence within the slice. If not found, returns `Err(usize)`
265 /// with the insertion point to maintain order.
266 ///
267 /// The comparison is performed element-by-element with early termination:
268 /// sequences with different lengths or any differing element are ordered
269 /// according to the first difference encountered.
270 ///
271 /// # Performance Note
272 ///
273 /// Each binary search probe **fully decodes a compressed sequence** until a
274 /// difference is found or the sequence ends. For `log(n)` probes, each
275 /// decoding is O(m) where `m` is the sequence length. This is O(m * log n)
276 /// overall.
277 ///
278 /// - If sequences are short or differ early, early termination makes this
279 /// very efficient.
280 /// - If sequences are very long and similar, decoding cost dominates.
281 /// - To extract a key from each sequence efficiently, use
282 /// [`binary_search_by_key`](Self::binary_search_by_key) to extract a
283 /// sortable key from the compressed data (e.g., first element) rather
284 /// than the full sequence.
285 ///
286 /// # Examples
287 ///
288 /// ```
289 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
290 /// use compressed_intvec::seq::{SeqVec, LESeqVec};
291 ///
292 /// let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6, 7], &[8]];
293 /// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
294 ///
295 /// let slice = vec.slice(0, 4).unwrap();
296 ///
297 /// assert_eq!(slice.binary_search(&[3, 4, 5]), Ok(1));
298 /// assert_eq!(slice.binary_search(&[6, 7]), Ok(2));
299 /// assert_eq!(slice.binary_search(&[5]), Err(2)); // Would be inserted at index 2
300 /// # Ok(())
301 /// # }
302 /// ```
303 pub fn binary_search(&self, sequence: &[T]) -> Result<usize, usize>
304 where
305 T: Ord,
306 {
307 self.binary_search_by(|probe_iter| {
308 // Compare element-by-element with early exit on first difference.
309 let mut probe_iter = probe_iter.peekable();
310 let mut seq_iter = sequence.iter().peekable();
311
312 loop {
313 match (probe_iter.next(), seq_iter.next()) {
314 (Some(a), Some(b)) => {
315 let cmp = a.cmp(b);
316 if cmp != Ordering::Equal {
317 return cmp;
318 }
319 }
320 // Probe sequence ended first → Less
321 (None, Some(_)) => return Ordering::Less,
322 // Target sequence ended first → Greater
323 (Some(_), None) => return Ordering::Greater,
324 // Both ended → Equal
325 (None, None) => return Ordering::Equal,
326 }
327 }
328 })
329 }
330
331 /// Binary searches this slice with a custom comparison function.
332 ///
333 /// The comparison function receives a [`SeqIter`] for the probe sequence
334 /// and should return the ordering relative to the target.
335 ///
336 /// # Performance Note
337 ///
338 /// The closure receives a [`SeqIter`] for the probe sequence, which may
339 /// require decoding the compressed data. Each probe can involve up to O(m)
340 /// decoding operations where `m` is the sequence length.
341 ///
342 /// - For fast key extraction (first element, hash, etc.), decode only what
343 /// is needed within the closure and return early.
344 /// - To search by a pre-computed key, use
345 /// [`binary_search_by_key`](Self::binary_search_by_key) instead, which is
346 /// optimized for key-based comparisons.
347 /// - For comparisons requiring the full sequence, full decoding is
348 /// unavoidable: O(m * log n).
349 ///
350 /// [`SeqIter`]: super::iter::SeqIter
351 ///
352 /// # Examples
353 ///
354 /// ```
355 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
356 /// use compressed_intvec::seq::{SeqVec, LESeqVec};
357 /// use std::cmp::Ordering;
358 ///
359 /// let sequences: &[&[u32]] = &[&[1], &[1, 2], &[1, 2, 3], &[1, 2, 3, 4]];
360 /// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
361 ///
362 /// let slice = vec.slice(0, 4).unwrap();
363 ///
364 /// // Search by sequence length (decodes all elements)
365 /// let result = slice.binary_search_by(|probe| {
366 /// let probe_len = probe.count();
367 /// probe_len.cmp(&3)
368 /// });
369 ///
370 /// assert_eq!(result, Ok(2));
371 ///
372 /// // Search by first element only (early termination)
373 /// let result = slice.binary_search_by(|mut probe| {
374 /// match probe.next() {
375 /// Some(first) => first.cmp(&1),
376 /// None => Ordering::Less,
377 /// }
378 /// });
379 /// # Ok(())
380 /// # }
381 /// ```
382 #[inline]
383 pub fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize>
384 where
385 F: FnMut(SeqIter<'_, T, E>) -> Ordering,
386 {
387 let mut low = 0;
388 let mut high = self.len();
389
390 while low < high {
391 let mid = low + (high - low) / 2;
392 // SAFETY: Bounds are checked by the loop invariants and the slice's
393 // construction, so the index is always valid.
394 let cmp = f(unsafe { self.get_unchecked(mid) });
395 match cmp {
396 Ordering::Less => low = mid + 1,
397 Ordering::Equal => return Ok(mid),
398 Ordering::Greater => high = mid,
399 }
400 }
401 Err(low)
402 }
403
404 /// Binary searches this slice with a key extraction function.
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
410 /// use compressed_intvec::seq::{SeqVec, LESeqVec};
411 ///
412 /// let sequences: &[&[u32]] = &[&[10], &[20], &[30, 40], &[50]];
413 /// let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;
414 ///
415 /// let slice = vec.slice(0, 4).unwrap();
416 ///
417 /// // Search by first element
418 /// let result = slice.binary_search_by_key(&30, |mut probe| probe.next().unwrap());
419 /// assert_eq!(result, Ok(2)); // Found sequence [30, 40]
420 /// # Ok(())
421 /// # }
422 /// ```
423 #[inline]
424 pub fn binary_search_by_key<K, F>(&self, b: &K, mut f: F) -> Result<usize, usize>
425 where
426 F: FnMut(SeqIter<'_, T, E>) -> K,
427 K: Ord,
428 {
429 self.binary_search_by(|probe| f(probe).cmp(b))
430 }
431}
432
433/// An iterator over the sequences of a [`SeqVecSlice`].
434///
435/// This struct is created by the [`iter`] method. Each element of this
436/// iterator is a [`SeqIter`] for a sequence within the slice.
437///
438/// [`iter`]: SeqVecSlice::iter
439/// [`SeqIter`]: super::iter::SeqIter
440pub struct SeqVecSliceIter<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> {
441 slice: &'a SeqVecSlice<'a, T, E, B>,
442 /// Current front index for forward iteration.
443 front: usize,
444 /// Current back index (exclusive) for backward iteration.
445 back: usize,
446}
447
448impl<T: Storable, E: Endianness, B: AsRef<[u64]>> fmt::Debug for SeqVecSliceIter<'_, T, E, B> {
449 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450 f.debug_struct("SeqVecSliceIter")
451 .field("remaining", &self.back.saturating_sub(self.front))
452 .finish()
453 }
454}
455
456// --- IntoIterator Implementation ---
457
458impl<'a, T, E, B> IntoIterator for &'a SeqVecSlice<'a, T, E, B>
459where
460 T: Storable,
461 E: Endianness,
462 B: AsRef<[u64]>,
463 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
464 + CodesRead<E>
465 + BitSeek<Error = core::convert::Infallible>,
466{
467 type Item = SeqIter<'a, T, E>;
468 type IntoIter = SeqVecSliceIter<'a, T, E, B>;
469
470 /// Returns an iterator over the sequences in the slice.
471 ///
472 /// This implementation allows slices to be used in `for` loops:
473 ///
474 /// ```no_run
475 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
476 /// # use compressed_intvec::seq::{SeqVec, LESeqVec};
477 /// # let vec: LESeqVec<u32> = SeqVec::from_slices(&[&[1, 2][..], &[3, 4, 5][..]])?;
478 /// # let slice = vec.slice(0, 2).unwrap();
479 /// for seq in &slice {
480 /// // Process each sequence
481 /// }
482 /// # Ok(())
483 /// # }
484 /// ```
485 #[inline]
486 fn into_iter(self) -> Self::IntoIter {
487 self.iter()
488 }
489}
490
491impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecSliceIter<'a, T, E, B> {
492 /// Creates a new iterator for a given [`SeqVecSlice`].
493 fn new(slice: &'a SeqVecSlice<'a, T, E, B>) -> Self {
494 Self {
495 slice,
496 front: 0,
497 back: slice.len(),
498 }
499 }
500}
501
502impl<'a, T, E, B> Iterator for SeqVecSliceIter<'a, T, E, B>
503where
504 T: Storable,
505 E: Endianness,
506 B: AsRef<[u64]>,
507 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
508 + CodesRead<E>
509 + BitSeek<Error = core::convert::Infallible>,
510{
511 type Item = SeqIter<'a, T, E>;
512
513 #[inline]
514 fn next(&mut self) -> Option<Self::Item> {
515 if self.front >= self.back {
516 return None;
517 }
518 let index = self.front;
519 self.front += 1;
520 // SAFETY: The iterator's invariant ensures `index` is in bounds.
521 Some(unsafe { self.slice.get_unchecked(index) })
522 }
523
524 fn size_hint(&self) -> (usize, Option<usize>) {
525 let remaining = self.back.saturating_sub(self.front);
526 (remaining, Some(remaining))
527 }
528
529 #[inline]
530 fn nth(&mut self, n: usize) -> Option<Self::Item> {
531 let remaining = self.back.saturating_sub(self.front);
532 if n >= remaining {
533 self.front = self.back;
534 return None;
535 }
536 self.front += n;
537 self.next()
538 }
539
540 #[inline]
541 fn count(self) -> usize {
542 self.back.saturating_sub(self.front)
543 }
544}
545
546impl<'a, T, E, B> ExactSizeIterator for SeqVecSliceIter<'a, T, E, B>
547where
548 T: Storable,
549 E: Endianness,
550 B: AsRef<[u64]>,
551 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
552 + CodesRead<E>
553 + BitSeek<Error = core::convert::Infallible>,
554{
555 fn len(&self) -> usize {
556 self.back.saturating_sub(self.front)
557 }
558}
559
560impl<'a, T, E, B> std::iter::FusedIterator for SeqVecSliceIter<'a, T, E, B>
561where
562 T: Storable,
563 E: Endianness,
564 B: AsRef<[u64]>,
565 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
566 + CodesRead<E>
567 + BitSeek<Error = core::convert::Infallible>,
568{
569}
570
571impl<'a, T, E, B> DoubleEndedIterator for SeqVecSliceIter<'a, T, E, B>
572where
573 T: Storable,
574 E: Endianness,
575 B: AsRef<[u64]>,
576 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
577 + CodesRead<E>
578 + BitSeek<Error = core::convert::Infallible>,
579{
580 #[inline]
581 fn next_back(&mut self) -> Option<Self::Item> {
582 if self.front >= self.back {
583 return None;
584 }
585 self.back -= 1;
586 // SAFETY: The iterator's invariant ensures `back` is in bounds.
587 Some(unsafe { self.slice.get_unchecked(self.back) })
588 }
589
590 #[inline]
591 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
592 let remaining = self.back.saturating_sub(self.front);
593 if n >= remaining {
594 self.back = self.front;
595 return None;
596 }
597 self.back -= n;
598 self.next_back()
599 }
600}
601
602// --- PartialEq Implementations ---
603
604impl<'a, T, E, B> PartialEq<SeqVecSlice<'a, T, E, B>> for SeqVecSlice<'a, T, E, B>
605where
606 T: Storable + PartialEq,
607 E: Endianness,
608 B: AsRef<[u64]>,
609 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
610 + CodesRead<E>
611 + BitSeek<Error = core::convert::Infallible>,
612{
613 fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool {
614 if self.len() != other.len() {
615 return false;
616 }
617 self.iter()
618 .zip(other.iter())
619 .all(|(seq_a, seq_b)| seq_a.eq(seq_b))
620 }
621}
622
623impl<'a, T, E, B> Eq for SeqVecSlice<'a, T, E, B>
624where
625 T: Storable + Eq,
626 E: Endianness,
627 B: AsRef<[u64]>,
628 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
629 + CodesRead<E>
630 + BitSeek<Error = core::convert::Infallible>,
631{
632}
633
634impl<'a, T, E, B> PartialEq<SeqVec<T, E, B>> for SeqVecSlice<'a, T, E, B>
635where
636 T: Storable + PartialEq,
637 E: Endianness,
638 B: AsRef<[u64]>,
639 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
640 + CodesRead<E>
641 + BitSeek<Error = core::convert::Infallible>,
642{
643 fn eq(&self, other: &SeqVec<T, E, B>) -> bool {
644 if self.len() != other.num_sequences() {
645 return false;
646 }
647 self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
648 }
649}
650
651impl<'a, T, E, B> PartialEq<SeqVecSlice<'a, T, E, B>> for SeqVec<T, E, B>
652where
653 T: Storable + PartialEq,
654 E: Endianness,
655 B: AsRef<[u64]>,
656 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
657 + CodesRead<E>
658 + BitSeek<Error = core::convert::Infallible>,
659{
660 fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool {
661 other.eq(self)
662 }
663}
664
665impl<'a, T, E, B> PartialEq<&SeqVec<T, E, B>> for SeqVecSlice<'a, T, E, B>
666where
667 T: Storable + PartialEq,
668 E: Endianness,
669 B: AsRef<[u64]>,
670 for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
671 + CodesRead<E>
672 + BitSeek<Error = core::convert::Infallible>,
673{
674 fn eq(&self, other: &&SeqVec<T, E, B>) -> bool {
675 self.eq(*other)
676 }
677}