Update readme; Clean up code; Update tests;
This commit is contained in:
parent
c764c4b724
commit
dcdec20b64
28 changed files with 79 additions and 173 deletions
|
@ -3,6 +3,12 @@
|
|||
This is the changelog of [Oct](https://crates.io/crates/oct/).
|
||||
See `README.md` for more information.
|
||||
|
||||
## 0.20.1
|
||||
|
||||
* Update readme
|
||||
* Clean up code
|
||||
* Update tests
|
||||
|
||||
## 0.20.0
|
||||
|
||||
* Remove `Vec::set_len`
|
||||
|
|
|
@ -9,7 +9,7 @@ members = ["oct", "oct-benchmarks", "oct-macros"]
|
|||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.20.0"
|
||||
version = "0.20.1"
|
||||
authors = ["Gabriel Bjørnager Jensen"]
|
||||
readme = "README.md"
|
||||
repository = "https://mandelbrot.dk/bjoernager/oct/"
|
||||
|
|
|
@ -33,8 +33,6 @@ According to my runs on an AMD Ryzen 7 3700X with default settings, these benchm
|
|||
| `decode_bool` | 1.037 | 1.099 | 1.041 | 1.101 |
|
||||
| **Total time** → | 12.957 | 11.690 | 9.238 | 21.091 |
|
||||
| **Total deviation (p.c.)** → | +40 | +27 | ±0 | +128 |
|
||||
| **Total time** → | 14.456 | 11.624 | 8.800 | 21.509 |
|
||||
| **Total deviation (p.c.)** → | +64 | +32 | ±0 | +144 |
|
||||
|
||||
[Bincode]: https://crates.io/crates/bincode/
|
||||
[Borsh]: https://crates.io/crates/borsh/
|
||||
|
|
|
@ -35,12 +35,12 @@ repository.workspace = true
|
|||
oct = { path = "../oct", version = "0.20", features = ["proc-macro"]}
|
||||
|
||||
bincode = "2.0"
|
||||
rand = "0.8"
|
||||
rand = "0.9"
|
||||
rayon = "1.10"
|
||||
zerocopy = "0.8"
|
||||
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
postcard = { version = "1.0", features = ["use-std"] }
|
||||
postcard = { version = "1.1", features = ["use-std"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[lints]
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
use core::array;
|
||||
use core::num::NonZero;
|
||||
use rand::random;
|
||||
use rand::distributions::{Distribution, Standard};
|
||||
use rand::distr::{Distribution, StandardUniform};
|
||||
use std::time::Instant;
|
||||
use zerocopy::{Immutable, IntoBytes};
|
||||
|
||||
|
@ -188,8 +188,8 @@ enum Enum {
|
|||
|
||||
fn generate_random_data<T>(item_size: usize, value_count: usize) -> impl Iterator<Item = u8>
|
||||
where
|
||||
T: Immutable + IntoBytes + Sized,
|
||||
Standard: Distribution<T>,
|
||||
T: Immutable + IntoBytes + Sized,
|
||||
StandardUniform: Distribution<T>,
|
||||
{
|
||||
let count = item_size * value_count;
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ use core::cell::{Cell, LazyCell, RefCell, UnsafeCell};
|
|||
use core::convert::Infallible;
|
||||
use core::ffi::{CStr, c_void};
|
||||
use core::hash::BuildHasher;
|
||||
use core::hint::unreachable_unchecked;
|
||||
use core::marker::{PhantomData, PhantomPinned};
|
||||
use core::net::{
|
||||
IpAddr,
|
||||
|
@ -415,9 +414,7 @@ impl Encode for Infallible {
|
|||
|
||||
#[inline(always)]
|
||||
fn encode(&self, _output: &mut Output) -> Result<(), Self::Error> {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() }
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A character could not be decoded.
|
||||
///
|
||||
|
@ -37,8 +36,6 @@ impl Error for CharDecodeError { }
|
|||
impl From<Infallible> for CharDecodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A collection could not be decoded.
|
||||
///
|
||||
|
@ -67,9 +66,7 @@ where
|
|||
impl<L, I> From<Infallible> for CollectionDecodeError<L, I> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A collection could not be encoded.
|
||||
///
|
||||
|
@ -60,9 +59,7 @@ where
|
|||
impl<L, I> From<Infallible> for CollectionEncodeError<L, I> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ use crate::decode::Decode;
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Debug, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// An enumeration could not be decoded.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
|
@ -72,9 +71,7 @@ where
|
|||
impl<T, D, F> From<Infallible> for EnumDecodeError<T, D, F> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Debug, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// An enumeration could not be encoded.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
|
@ -57,9 +56,7 @@ where
|
|||
impl<D, F> From<Infallible> for EnumEncodeError<D, F> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ use crate::error::{
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A generic decoding error type.
|
||||
///
|
||||
|
@ -127,9 +126,7 @@ where
|
|||
impl From<Infallible> for GenericDecodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() }
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ use core::cell::BorrowError;
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A generic encoding error type.
|
||||
///
|
||||
|
@ -113,9 +112,7 @@ where
|
|||
impl From<Infallible> for GenericEncodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() }
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// An input-related error.
|
||||
///
|
||||
|
@ -45,8 +44,6 @@ impl Error for InputError { }
|
|||
impl From<Infallible> for InputError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// An [`isize`] value could not be decoded.
|
||||
///
|
||||
|
@ -39,8 +38,6 @@ impl Error for IsizeEncodeError { }
|
|||
impl From<Infallible> for IsizeEncodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Debug, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A collection's item could not be decoded.
|
||||
///
|
||||
|
@ -49,9 +48,7 @@ where
|
|||
impl<I, E> From<Infallible> for ItemDecodeError<I, E> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Debug, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A collection's item could not be encoded.
|
||||
///
|
||||
|
@ -49,9 +48,7 @@ where
|
|||
impl<I, E> From<Infallible> for ItemEncodeError<I, E> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A collection buffer was too small to contain all of its elements.
|
||||
///
|
||||
|
@ -41,8 +40,6 @@ impl Error for LengthError { }
|
|||
impl From<Infallible> for LengthError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A non-zero integer could not be decoded.
|
||||
///
|
||||
|
@ -29,8 +28,6 @@ impl Error for NonZeroDecodeError { }
|
|||
impl From<Infallible> for NonZeroDecodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[must_use]
|
||||
|
@ -45,8 +44,6 @@ impl Error for OutputError { }
|
|||
impl From<Infallible> for OutputError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use core::cell::BorrowError;
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A reference cell could not be encoded.
|
||||
///
|
||||
|
@ -54,8 +53,6 @@ impl<E: Error + 'static> Error for RefCellEncodeError<E> {
|
|||
impl<E> From<Infallible> for RefCellEncodeError<E> {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// The [`SystemTime`](std::time::SystemTime) type could not represent a UNIX timestamp.
|
||||
///
|
||||
|
@ -34,8 +33,6 @@ impl Error for SystemTimeDecodeError { }
|
|||
impl From<Infallible> for SystemTimeDecodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// A [`usize`] value could not be decoded.
|
||||
///
|
||||
|
@ -38,8 +37,6 @@ impl Error for UsizeEncodeError { }
|
|||
impl From<Infallible> for UsizeEncodeError {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::{self, Display, Formatter};
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
/// An invalid UTF-8 sequence was encountered.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
|
@ -34,8 +33,6 @@ impl Error for Utf8Error { }
|
|||
impl From<Infallible> for Utf8Error {
|
||||
#[inline(always)]
|
||||
fn from(_value: Infallible) -> Self {
|
||||
// SAFETY: `Infallible` objects can never be con-
|
||||
// structed.
|
||||
unsafe { unreachable_unchecked() };
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@
|
|||
//! The following is an example of a UDP server/client for geographic data:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #[cfg(not(miri))]
|
||||
//! # {
|
||||
//! use oct::decode::Decode;
|
||||
//! use oct::encode::{Encode, SizedEncode};
|
||||
//! use oct::slot::Slot;
|
||||
|
@ -177,6 +179,8 @@
|
|||
//! let response = response_buf.read().unwrap();
|
||||
//! assert_eq!(response, Response::AtmosphericTemperature(44.4));
|
||||
//! });
|
||||
//!
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Feature flags
|
||||
|
|
|
@ -74,7 +74,7 @@ impl<T, const N: usize> IntoIter<T, N> {
|
|||
// SAFETY: It is not invalid for us to go one-past-
|
||||
// the-end or exceed `isize::MAX`; `len` guarantees
|
||||
// that this counter will not be used as a pointer
|
||||
// offset if this would happen.
|
||||
// offset in such cases.
|
||||
self.pos = unsafe { self.pos.unchecked_add(count) };
|
||||
}
|
||||
|
||||
|
@ -95,16 +95,37 @@ impl<T, const N: usize> IntoIter<T, N> {
|
|||
self.len = unsafe { self.len.unchecked_sub(count) };
|
||||
}
|
||||
|
||||
/// Gets a slice of the remaining elements.
|
||||
/// Gets a pointer to the current element.
|
||||
///
|
||||
/// If the iterator `self` is currently empty, then the returned pointer will instead be dangling.
|
||||
#[inline(always)]
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
fn as_ptr(&self) -> *const T {
|
||||
let pos = self.pos;
|
||||
let len = self.len;
|
||||
|
||||
// SAFETY: `MaybeUninit<T>` is transparent to `T`.
|
||||
let base = self.buf.as_ptr() as *const T;
|
||||
|
||||
let ptr = unsafe { base.add(pos) };
|
||||
unsafe { base.add(pos) }
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the current element.
|
||||
///
|
||||
/// If the iterator `self` is currently empty, then the returned pointer will instead be dangling.
|
||||
#[inline(always)]
|
||||
fn as_mut_ptr(&mut self) -> *mut T {
|
||||
let pos = self.pos;
|
||||
|
||||
// SAFETY: `MaybeUninit<T>` is transparent to `T`.
|
||||
let base = self.buf.as_mut_ptr() as *mut T;
|
||||
|
||||
unsafe { base.add(pos) }
|
||||
}
|
||||
|
||||
/// Gets a slice of the remaining elements.
|
||||
#[inline(always)]
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
let len = self.len;
|
||||
let ptr = self.as_ptr();
|
||||
|
||||
unsafe { slice::from_raw_parts(ptr, len) }
|
||||
}
|
||||
|
@ -112,13 +133,8 @@ impl<T, const N: usize> IntoIter<T, N> {
|
|||
/// Gets a mutable slice of the remaining elements.
|
||||
#[inline(always)]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
let pos = self.pos;
|
||||
let len = self.len;
|
||||
|
||||
// SAFETY: `MaybeUninit<T>` is transparent to `T`.
|
||||
let base = self.buf.as_mut_ptr() as *mut T;
|
||||
|
||||
let ptr = unsafe { base.add(pos) };
|
||||
let ptr = self.as_mut_ptr();
|
||||
|
||||
unsafe { slice::from_raw_parts_mut(ptr, len) }
|
||||
}
|
||||
|
@ -180,7 +196,9 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
// Test whether the iterator is empty.
|
||||
|
||||
if self.len == 0x0 { return None };
|
||||
if self.len == 0x0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Take the next value.
|
||||
|
||||
|
@ -198,11 +216,6 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
|
||||
// Read the item value.
|
||||
|
||||
// SAFETY: We guarantee that all items in the range
|
||||
//
|
||||
// self.pos..self.pos + self.len
|
||||
//
|
||||
// are alive (and initialised).
|
||||
let value = unsafe { item.read() };
|
||||
|
||||
// Update counters, **not** including the position.
|
||||
|
@ -213,64 +226,6 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
|
||||
Some(value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
// Test whether the iterator is empty.
|
||||
|
||||
if n >= self.len { return None };
|
||||
|
||||
// SAFETY: We have tested that there are at least
|
||||
// `n + 1` elements left.
|
||||
|
||||
// Get the indeces of the involved items.
|
||||
|
||||
let end = self.pos + self.len;
|
||||
let index = end - n;
|
||||
let start = index + 0x1;
|
||||
|
||||
// SAFETY: `MaybeUninit<T>` is transparent to `T`.
|
||||
let base = self.buf.as_mut_ptr() as *mut T;
|
||||
|
||||
// Drop each skipped element in **reverse** order.
|
||||
|
||||
for i in (start..end).rev() {
|
||||
let item = unsafe { base.add(i) };
|
||||
|
||||
// SAFETY: We guarantee that all items in the range
|
||||
//
|
||||
// self.pos..self.pos + self.len
|
||||
//
|
||||
// are alive (and initialised).
|
||||
unsafe { drop_in_place(item) };
|
||||
}
|
||||
|
||||
// Read the final value.
|
||||
|
||||
let item = unsafe { base.add(index) };
|
||||
|
||||
// SAFETY: We guarantee that all items in the range
|
||||
//
|
||||
// self.pos..self.pos + self.len
|
||||
//
|
||||
// are alive (and initialised).
|
||||
let value = unsafe { item.read() };
|
||||
|
||||
// Update counters, **not** including the position.
|
||||
|
||||
// SAFETY: This cannot overflow as `n` has been
|
||||
// tested to be less than `self.len`, which itself
|
||||
// cannot be greater than `isize::MAX`.
|
||||
let count = unsafe { n.unchecked_add(0x1) };
|
||||
|
||||
// SAFETY: We have tested that there are at least
|
||||
// `count` elements left.
|
||||
unsafe { self.advance_back_by_unchecked(count) };
|
||||
|
||||
// Return the value.
|
||||
|
||||
Some(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const N: usize> Drop for IntoIter<T, N> {
|
||||
|
@ -302,7 +257,9 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Test whether the iterator is empty.
|
||||
|
||||
if self.len == 0x0 { return None };
|
||||
if self.len == 0x0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Take the next value.
|
||||
|
||||
|
@ -341,19 +298,23 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
// Test whether the iterator is empty.
|
||||
|
||||
if n >= self.len { return None };
|
||||
if n >= self.len {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Get the indeces of the involved items.
|
||||
// Get the indices of the involved items.
|
||||
|
||||
let start = self.pos;
|
||||
let end = start + n;
|
||||
let drop_start = self.pos;
|
||||
let drop_end = drop_start + n;
|
||||
|
||||
let index = drop_end;
|
||||
|
||||
// SAFETY: `MaybeUninit<T>` is transparent to `T`.
|
||||
let base = self.buf.as_mut_ptr() as *mut T;
|
||||
|
||||
// Drop each skipped element.
|
||||
|
||||
for i in start..end {
|
||||
for i in drop_start..drop_end {
|
||||
let item = unsafe { base.add(i) };
|
||||
|
||||
// SAFETY: We guarantee that all items in the range
|
||||
|
@ -366,13 +327,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
|
||||
// Read the final value.
|
||||
|
||||
let item = unsafe { base.add(end) };
|
||||
|
||||
// SAFETY: We guarantee that all items in the range
|
||||
//
|
||||
// self.pos..self.pos + self.len
|
||||
//
|
||||
// are alive (and initialised).
|
||||
let item = unsafe { base.add(index) };
|
||||
let value = unsafe { item.read() };
|
||||
|
||||
// Update counters.
|
||||
|
|
|
@ -270,7 +270,7 @@ impl<T, const N: usize> Vec<T, N> {
|
|||
debug_assert!(len <= N, "cannot set length past bounds");
|
||||
|
||||
// SAFETY: The caller guarantees that `len` is not
|
||||
// be freaky.
|
||||
// freaky.
|
||||
self.len = len
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue