use super::BStackAllocator;
use crate::BStack;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::io;
use std::ops::Range;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct BStackRange {
offset: u64,
len: u64,
}
impl BStackRange {
pub unsafe fn from_raw_parts(offset: u64, len: u64) -> Self {
Self { offset, len }
}
#[inline]
pub fn new(offset: u64, len: u64) -> Self {
Self {
offset,
len: len.min(u64::MAX - offset),
}
}
pub fn empty() -> Self {
Self { offset: 0, len: 0 }
}
#[inline]
pub fn start(&self) -> u64 {
self.offset
}
#[inline]
pub fn end(&self) -> u64 {
self.offset + self.len
}
#[inline]
pub fn len(&self) -> u64 {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn range(&self) -> Range<u64> {
self.offset..self.offset + self.len
}
#[inline]
pub fn to_bytes(self) -> [u8; 16] {
let mut out = [0u8; 16];
out[..8].copy_from_slice(&self.offset.to_le_bytes());
out[8..].copy_from_slice(&self.len.to_le_bytes());
out
}
#[inline]
pub fn from_bytes(bytes: [u8; 16]) -> Self {
let offset = u64::from_le_bytes(bytes[..8].try_into().unwrap());
let len = u64::from_le_bytes(bytes[8..].try_into().unwrap());
Self::new(offset, len)
}
}
impl PartialOrd for BStackRange {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for BStackRange {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.offset
.cmp(&other.offset)
.then(self.len.cmp(&other.len))
}
}
impl From<BStackRange> for [u8; 16] {
#[inline]
fn from(r: BStackRange) -> Self {
r.to_bytes()
}
}
impl From<Range<u64>> for BStackRange {
#[inline]
fn from(r: Range<u64>) -> Self {
BStackRange {
offset: r.start,
len: r.end.saturating_sub(r.start),
}
}
}
impl From<BStackRange> for Range<u64> {
#[inline]
fn from(range: BStackRange) -> Self {
range.offset..range.offset + range.len
}
}
impl fmt::Debug for BStackRange {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BStackRange")
.field("start", &self.start())
.field("end", &self.end())
.field("len", &self.len())
.finish_non_exhaustive()
}
}
pub struct BStackSlice<'a> {
stack: &'a BStack,
range: BStackRange,
}
impl<'a> Clone for BStackSlice<'a> {
#[inline]
fn clone(&self) -> Self {
BStackSlice {
stack: self.stack,
range: self.range,
}
}
}
impl<'a> fmt::Debug for BStackSlice<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BStackSlice")
.field("start", &self.start())
.field("end", &self.end())
.field("len", &self.len())
.finish_non_exhaustive()
}
}
impl<'a> BStackSlice<'a> {
#[inline]
pub unsafe fn from_raw_parts(stack: &'a BStack, offset: u64, len: u64) -> Self {
Self {
stack,
range: unsafe { BStackRange::from_raw_parts(offset, len) },
}
}
#[inline]
pub unsafe fn from_raw_range(stack: &'a BStack, range: BStackRange) -> Self {
Self { stack, range }
}
#[inline]
pub fn empty(stack: &'a BStack) -> Self {
Self {
stack,
range: BStackRange::empty(),
}
}
#[inline]
pub fn start(&self) -> u64 {
self.range.start()
}
#[inline]
pub fn end(&self) -> u64 {
self.range.end()
}
#[inline]
pub fn len(&self) -> u64 {
self.range.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.range.is_empty()
}
#[inline]
pub fn range(&self) -> Range<u64> {
self.range.range()
}
#[inline]
pub fn as_range(&self) -> BStackRange {
self.range
}
#[inline]
pub fn to_bytes(&self) -> [u8; 16] {
self.range.to_bytes()
}
#[inline]
pub unsafe fn from_bytes(stack: &'a BStack, bytes: [u8; 16]) -> Self {
Self {
stack,
range: BStackRange::from_bytes(bytes),
}
}
#[inline]
pub fn stack(&self) -> &'a BStack {
self.stack
}
#[inline]
pub fn subslice(&self, start: u64, end: u64) -> BStackSlice<'a> {
self.subslice_range(start..end)
}
pub fn subslice_range(&self, range: Range<u64>) -> BStackSlice<'a> {
assert!(range.start <= range.end, "range start must be <= end");
assert!(range.end <= self.len(), "range end must be <= slice length");
BStackSlice {
stack: self.stack,
range: unsafe {
BStackRange::from_raw_parts(self.start() + range.start, range.end - range.start)
},
}
}
#[inline]
pub fn read(&self) -> io::Result<Vec<u8>> {
self.stack.get(self.start(), self.end())
}
#[inline]
pub fn read_into(&self, buf: &mut [u8]) -> io::Result<()> {
let n = (buf.len() as u64).min(self.len()) as usize;
self.stack.get_into(self.start(), &mut buf[..n])
}
pub fn read_range(&self, start: u64, end: u64) -> io::Result<Vec<u8>> {
if end > self.len() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("range [{start}, {end}) exceeds slice length {}", self.len()),
));
}
self.stack.get(self.start() + start, self.start() + end)
}
pub fn read_range_into(&self, start: u64, buf: &mut [u8]) -> io::Result<()> {
let end_rel = start + buf.len() as u64;
if end_rel > self.len() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"range [{start}, {end_rel}) exceeds slice length {}",
self.len()
),
));
}
self.stack.get_into(self.start() + start, buf)
}
#[cfg(feature = "set")]
pub fn write(&mut self, data: impl AsRef<[u8]>) -> io::Result<()> {
let data = data.as_ref();
let n = (data.len() as u64).min(self.len()) as usize;
self.stack.set(self.start(), &data[..n])
}
#[cfg(feature = "set")]
pub fn write_range(&mut self, start: u64, data: impl AsRef<[u8]>) -> io::Result<()> {
let data = data.as_ref();
let end_rel = start + data.len() as u64;
if end_rel > self.len() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"range [{start}, {end_rel}) exceeds slice length {}",
self.len()
),
));
}
self.stack.set(self.start() + start, data)
}
#[cfg(feature = "set")]
#[inline]
pub fn zero(&mut self) -> io::Result<()> {
self.stack.zero(self.start(), self.len())
}
#[cfg(feature = "set")]
pub fn zero_range(&mut self, start: u64, n: u64) -> io::Result<()> {
let end_rel = start + n;
if end_rel > self.len() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"range [{start}, {end_rel}) exceeds slice length {}",
self.len()
),
));
}
self.stack.zero(self.start() + start, n)
}
#[inline]
pub fn reader(&self) -> BStackSliceReader<'a> {
BStackSliceReader {
slice: self.clone(),
cursor: 0,
}
}
#[inline]
pub fn reader_at(&self, offset: u64) -> BStackSliceReader<'a> {
BStackSliceReader {
slice: self.clone(),
cursor: offset,
}
}
#[cfg(feature = "set")]
#[inline]
pub fn writer(self) -> BStackSliceWriter<'a> {
BStackSliceWriter {
slice: self,
cursor: 0,
}
}
#[cfg(feature = "set")]
#[inline]
pub fn writer_at(self, offset: u64) -> BStackSliceWriter<'a> {
BStackSliceWriter {
slice: self,
cursor: offset,
}
}
}
impl<'a> PartialEq for BStackSlice<'a> {
fn eq(&self, other: &Self) -> bool {
self.range == other.range
}
}
impl<'a> Eq for BStackSlice<'a> {}
impl<'a> Hash for BStackSlice<'a> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.range.hash(state);
}
}
impl<'a> PartialOrd for BStackSlice<'a> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for BStackSlice<'a> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.range.cmp(&other.range)
}
}
impl<'a> From<BStackSlice<'a>> for BStackRange {
#[inline]
fn from(s: BStackSlice<'a>) -> BStackRange {
s.range
}
}
impl<'a> From<BStackSlice<'a>> for [u8; 16] {
#[inline]
fn from(s: BStackSlice<'a>) -> Self {
s.range.to_bytes()
}
}
impl<'a> From<BStackSlice<'a>> for BStackSliceReader<'a> {
#[inline]
fn from(slice: BStackSlice<'a>) -> Self {
BStackSliceReader { slice, cursor: 0 }
}
}
#[cfg(feature = "set")]
impl<'a> From<BStackSlice<'a>> for BStackSliceWriter<'a> {
#[inline]
fn from(slice: BStackSlice<'a>) -> Self {
BStackSliceWriter { slice, cursor: 0 }
}
}
pub struct BStackOwnedSlice<'a, A: BStackAllocator> {
allocator: &'a A,
range: BStackRange,
}
impl<'a, A: BStackAllocator> fmt::Debug for BStackOwnedSlice<'a, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BStackOwnedSlice")
.field("start", &self.start())
.field("end", &self.end())
.field("len", &self.len())
.finish_non_exhaustive()
}
}
impl<'a, A: BStackAllocator> BStackOwnedSlice<'a, A> {
#[inline]
pub unsafe fn from_raw_parts(allocator: &'a A, offset: u64, len: u64) -> Self {
Self {
allocator,
range: unsafe { BStackRange::from_raw_parts(offset, len) },
}
}
#[inline]
pub unsafe fn from_raw_range(allocator: &'a A, range: BStackRange) -> Self {
Self { allocator, range }
}
#[inline]
pub fn empty(allocator: &'a A) -> Self {
Self {
allocator,
range: BStackRange::empty(),
}
}
#[inline]
pub fn start(&self) -> u64 {
self.range.start()
}
#[inline]
pub fn end(&self) -> u64 {
self.range.end()
}
#[inline]
pub fn len(&self) -> u64 {
self.range.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.range.is_empty()
}
#[inline]
pub fn range(&self) -> Range<u64> {
self.range.range()
}
#[inline]
pub fn as_range(&self) -> BStackRange {
self.range
}
#[inline]
pub fn to_bytes(&self) -> [u8; 16] {
self.range.to_bytes()
}
#[inline]
pub unsafe fn from_bytes(allocator: &'a A, bytes: [u8; 16]) -> Self {
Self {
allocator,
range: BStackRange::from_bytes(bytes),
}
}
#[inline]
pub fn allocator(&self) -> &'a A {
self.allocator
}
#[inline]
pub fn as_slice<'s>(&'s self) -> BStackSlice<'s> {
BStackSlice {
stack: self.allocator.stack(),
range: self.range,
}
}
#[inline]
pub fn as_slice_mut<'s>(&'s mut self) -> BStackSlice<'s> {
BStackSlice {
stack: self.allocator.stack(),
range: self.range,
}
}
#[inline]
pub fn read(&self) -> io::Result<Vec<u8>> {
self.as_slice().read()
}
#[inline]
pub fn read_into(&self, buf: &mut [u8]) -> io::Result<()> {
self.as_slice().read_into(buf)
}
#[inline]
pub fn read_range(&self, start: u64, end: u64) -> io::Result<Vec<u8>> {
self.as_slice().read_range(start, end)
}
#[inline]
pub fn read_range_into(&self, start: u64, buf: &mut [u8]) -> io::Result<()> {
self.as_slice().read_range_into(start, buf)
}
#[cfg(feature = "set")]
#[inline]
pub fn write(&mut self, data: impl AsRef<[u8]>) -> io::Result<()> {
self.as_slice_mut().write(data)
}
#[cfg(feature = "set")]
#[inline]
pub fn write_range(&mut self, start: u64, data: impl AsRef<[u8]>) -> io::Result<()> {
self.as_slice_mut().write_range(start, data)
}
#[cfg(feature = "set")]
#[inline]
pub fn zero(&mut self) -> io::Result<()> {
self.as_slice_mut().zero()
}
#[cfg(feature = "set")]
#[inline]
pub fn zero_range(&mut self, start: u64, n: u64) -> io::Result<()> {
self.as_slice_mut().zero_range(start, n)
}
#[inline]
pub fn reader<'s>(&'s self) -> BStackSliceReader<'s> {
self.as_slice().reader()
}
#[inline]
pub fn reader_at<'s>(&'s self, offset: u64) -> BStackSliceReader<'s> {
self.as_slice().reader_at(offset)
}
#[cfg(feature = "set")]
#[inline]
pub fn writer<'s>(&'s mut self) -> BStackSliceWriter<'s> {
self.as_slice_mut().writer()
}
#[cfg(feature = "set")]
#[inline]
pub fn writer_at<'s>(&'s mut self, offset: u64) -> BStackSliceWriter<'s> {
self.as_slice_mut().writer_at(offset)
}
}
impl<'a, A: BStackAllocator> PartialEq for BStackOwnedSlice<'a, A> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.range == other.range
}
}
impl<'a, A: BStackAllocator> Eq for BStackOwnedSlice<'a, A> {}
impl<'a, A: BStackAllocator> Hash for BStackOwnedSlice<'a, A> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.range.hash(state);
}
}
impl<'a, A: BStackAllocator> PartialOrd for BStackOwnedSlice<'a, A> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<'a, A: BStackAllocator> Ord for BStackOwnedSlice<'a, A> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.range.cmp(&other.range)
}
}
impl<'a, A: BStackAllocator> From<BStackOwnedSlice<'a, A>> for BStackRange {
#[inline]
fn from(s: BStackOwnedSlice<'a, A>) -> BStackRange {
s.range
}
}
impl<'a, A: BStackAllocator> From<BStackOwnedSlice<'a, A>> for [u8; 16] {
#[inline]
fn from(s: BStackOwnedSlice<'a, A>) -> Self {
s.range.to_bytes()
}
}
pub struct BStackSliceReader<'a> {
slice: BStackSlice<'a>,
cursor: u64,
}
impl<'a> Clone for BStackSliceReader<'a> {
fn clone(&self) -> Self {
BStackSliceReader {
slice: self.slice.clone(),
cursor: self.cursor,
}
}
}
impl<'a> fmt::Debug for BStackSliceReader<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BStackSliceReader")
.field("start", &self.slice.start())
.field("end", &self.slice.end())
.field("len", &self.slice.len())
.field("cursor", &self.cursor)
.finish_non_exhaustive()
}
}
impl<'a> BStackSliceReader<'a> {
#[inline]
pub fn position(&self) -> u64 {
self.cursor
}
#[inline]
pub fn into_slice(self) -> BStackSlice<'a> {
self.slice
}
#[inline]
pub fn slice(&self) -> &BStackSlice<'a> {
&self.slice
}
}
impl<'a> io::Read for BStackSliceReader<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if buf.is_empty() || self.cursor >= self.slice.len() {
return Ok(0);
}
let available = (self.slice.len() - self.cursor) as usize;
let n = buf.len().min(available);
let abs_start = self.slice.start() + self.cursor;
self.slice.stack.get_into(abs_start, &mut buf[..n])?;
self.cursor += n as u64;
Ok(n)
}
}
impl<'a> io::Seek for BStackSliceReader<'a> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
let len = self.slice.len() as i128;
let new_pos = match pos {
io::SeekFrom::Start(n) => n as i128,
io::SeekFrom::End(n) => len + n as i128,
io::SeekFrom::Current(n) => self.cursor as i128 + n as i128,
};
if new_pos < 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"seek before beginning of slice",
));
}
self.cursor = new_pos as u64;
Ok(self.cursor)
}
}
impl<'a> PartialEq for BStackSliceReader<'a> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.slice == other.slice && self.cursor == other.cursor
}
}
impl<'a> Eq for BStackSliceReader<'a> {}
impl<'a> Hash for BStackSliceReader<'a> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.slice.hash(state);
self.cursor.hash(state);
}
}
impl<'a> PartialOrd for BStackSliceReader<'a> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for BStackSliceReader<'a> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let self_pos = self.slice.start() + self.cursor;
let other_pos = other.slice.start() + other.cursor;
self_pos
.cmp(&other_pos)
.then(self.slice.len().cmp(&other.slice.len()))
}
}
impl<'a> From<BStackSliceReader<'a>> for BStackSlice<'a> {
#[inline]
fn from(r: BStackSliceReader<'a>) -> Self {
r.into_slice()
}
}
impl<'a> PartialEq<BStackSlice<'a>> for BStackSliceReader<'a> {
#[inline]
fn eq(&self, other: &BStackSlice<'a>) -> bool {
&self.slice == other
}
}
impl<'a> PartialEq<BStackSliceReader<'a>> for BStackSlice<'a> {
#[inline]
fn eq(&self, other: &BStackSliceReader<'a>) -> bool {
self == &other.slice
}
}
impl<'a> PartialOrd<BStackSlice<'a>> for BStackSliceReader<'a> {
#[inline]
fn partial_cmp(&self, other: &BStackSlice<'a>) -> Option<std::cmp::Ordering> {
Some(self.slice.cmp(other))
}
}
impl<'a> PartialOrd<BStackSliceReader<'a>> for BStackSlice<'a> {
#[inline]
fn partial_cmp(&self, other: &BStackSliceReader<'a>) -> Option<std::cmp::Ordering> {
Some(self.cmp(&other.slice))
}
}
#[cfg(feature = "set")]
pub struct BStackSliceWriter<'a> {
slice: BStackSlice<'a>,
cursor: u64,
}
#[cfg(feature = "set")]
impl<'a> fmt::Debug for BStackSliceWriter<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BStackSliceWriter")
.field("start", &self.slice.start())
.field("end", &self.slice.end())
.field("len", &self.slice.len())
.field("cursor", &self.cursor)
.finish_non_exhaustive()
}
}
#[cfg(feature = "set")]
impl<'a> BStackSliceWriter<'a> {
#[inline]
pub fn position(&self) -> u64 {
self.cursor
}
#[inline]
pub fn into_slice(self) -> BStackSlice<'a> {
self.slice
}
#[inline]
pub fn slice(&self) -> &BStackSlice<'a> {
&self.slice
}
}
#[cfg(feature = "set")]
impl<'a> io::Write for BStackSliceWriter<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if buf.is_empty() || self.cursor >= self.slice.len() {
return Ok(0);
}
let available = (self.slice.len() - self.cursor) as usize;
let n = buf.len().min(available);
let abs_start = self.slice.start() + self.cursor;
self.slice.stack.set(abs_start, &buf[..n])?;
self.cursor += n as u64;
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[cfg(feature = "set")]
impl<'a> io::Seek for BStackSliceWriter<'a> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
let len = self.slice.len() as i128;
let new_pos = match pos {
io::SeekFrom::Start(n) => n as i128,
io::SeekFrom::End(n) => len + n as i128,
io::SeekFrom::Current(n) => self.cursor as i128 + n as i128,
};
if new_pos < 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"seek before beginning of slice",
));
}
self.cursor = new_pos as u64;
Ok(self.cursor)
}
}
#[cfg(feature = "set")]
impl<'a> PartialEq for BStackSliceWriter<'a> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.slice == other.slice && self.cursor == other.cursor
}
}
#[cfg(feature = "set")]
impl<'a> Eq for BStackSliceWriter<'a> {}
#[cfg(feature = "set")]
impl<'a> Hash for BStackSliceWriter<'a> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.slice.hash(state);
self.cursor.hash(state);
}
}
#[cfg(feature = "set")]
impl<'a> PartialOrd for BStackSliceWriter<'a> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
#[cfg(feature = "set")]
impl<'a> Ord for BStackSliceWriter<'a> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let self_pos = self.slice.start() + self.cursor;
let other_pos = other.slice.start() + other.cursor;
self_pos
.cmp(&other_pos)
.then(self.slice.len().cmp(&other.slice.len()))
}
}
#[cfg(feature = "set")]
impl<'a> From<BStackSliceWriter<'a>> for BStackSlice<'a> {
#[inline]
fn from(w: BStackSliceWriter<'a>) -> Self {
w.into_slice()
}
}
#[cfg(feature = "set")]
impl<'a> From<BStackSliceReader<'a>> for BStackSliceWriter<'a> {
#[inline]
fn from(r: BStackSliceReader<'a>) -> Self {
BStackSliceWriter {
slice: r.slice,
cursor: r.cursor,
}
}
}
#[cfg(feature = "set")]
impl<'a> From<BStackSliceWriter<'a>> for BStackSliceReader<'a> {
#[inline]
fn from(w: BStackSliceWriter<'a>) -> Self {
BStackSliceReader {
slice: w.slice,
cursor: w.cursor,
}
}
}
#[cfg(feature = "set")]
impl<'a> PartialEq<BStackSliceWriter<'a>> for BStackSliceReader<'a> {
#[inline]
fn eq(&self, other: &BStackSliceWriter<'a>) -> bool {
self.slice == other.slice && self.cursor == other.cursor
}
}
#[cfg(feature = "set")]
impl<'a> PartialEq<BStackSliceReader<'a>> for BStackSliceWriter<'a> {
#[inline]
fn eq(&self, other: &BStackSliceReader<'a>) -> bool {
self.slice == other.slice && self.cursor == other.cursor
}
}
#[cfg(feature = "set")]
impl<'a> PartialEq<BStackSlice<'a>> for BStackSliceWriter<'a> {
#[inline]
fn eq(&self, other: &BStackSlice<'a>) -> bool {
&self.slice == other
}
}
#[cfg(feature = "set")]
impl<'a> PartialEq<BStackSliceWriter<'a>> for BStackSlice<'a> {
#[inline]
fn eq(&self, other: &BStackSliceWriter<'a>) -> bool {
self == &other.slice
}
}
#[cfg(feature = "set")]
impl<'a> PartialOrd<BStackSlice<'a>> for BStackSliceWriter<'a> {
#[inline]
fn partial_cmp(&self, other: &BStackSlice<'a>) -> Option<std::cmp::Ordering> {
Some(self.slice.cmp(other))
}
}
#[cfg(feature = "set")]
impl<'a> PartialOrd<BStackSliceWriter<'a>> for BStackSliceReader<'a> {
fn partial_cmp(&self, other: &BStackSliceWriter<'a>) -> Option<std::cmp::Ordering> {
let self_pos = self.slice.start() + self.cursor;
let other_pos = other.slice.start() + other.cursor;
Some(
self_pos
.cmp(&other_pos)
.then(self.slice.len().cmp(&other.slice.len())),
)
}
}
#[cfg(feature = "set")]
impl<'a> PartialOrd<BStackSliceReader<'a>> for BStackSliceWriter<'a> {
fn partial_cmp(&self, other: &BStackSliceReader<'a>) -> Option<std::cmp::Ordering> {
let self_pos = self.slice.start() + self.cursor;
let other_pos = other.slice.start() + other.cursor;
Some(
self_pos
.cmp(&other_pos)
.then(self.slice.len().cmp(&other.slice.len())),
)
}
}