diff --git a/src/id_wrapper.rs b/src/blazemap_id.rs similarity index 100% rename from src/id_wrapper.rs rename to src/blazemap_id.rs diff --git a/src/collections/blazemap.rs b/src/collections/blazemap.rs index 0309e22..005fe1e 100644 --- a/src/collections/blazemap.rs +++ b/src/collections/blazemap.rs @@ -14,12 +14,12 @@ use { }, }; +use crate::blazemap_id::BlazeMapId; use crate::collections::blazemap::entry::VacantEntryInner; pub use crate::collections::blazemap::{ entry::{Entry, OccupiedEntry, VacantEntry}, iter::{Drain, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut}, }; -use crate::id_wrapper::BlazeMapId; use crate::orig_type_id_map::StaticInfoApi; mod entry; diff --git a/src/lib.rs b/src/lib.rs index 357bd42..425e800 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,9 @@ //! and also implements a [vector-based slab-like map](prelude::BlazeMap) //! with an interface similar to that of [`HashMap`](std::collections::HashMap). +mod blazemap_id; /// Collection types. pub mod collections; -mod id_wrapper; mod macros; #[doc(hidden)] pub mod orig_type_id_map; @@ -15,8 +15,8 @@ pub mod utils; /// Crate prelude. pub mod prelude { pub use crate::{ + blazemap_id::{AllInstancesIter, BlazeMapId, BlazeMapIdWrapper}, collections::blazemap::BlazeMap, - id_wrapper::{AllInstancesIter, BlazeMapId, BlazeMapIdWrapper}, register_blazemap_id, register_blazemap_id_wrapper, }; } diff --git a/src/macros.rs b/src/macros.rs index 5fc6730..48f2df2 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -170,7 +170,7 @@ macro_rules! blazemap_id_wrapper_inner { $(#[$attrs])* #[derive(Clone, Copy, Eq, PartialEq, Hash)] #[repr(transparent)] - $vis struct $new_type($crate::utils::PrivateIndex); + $vis struct $new_type($crate::utils::OffsetProvider); impl $new_type { @@ -189,12 +189,12 @@ macro_rules! blazemap_id_wrapper_inner { #[inline] fn get_index(self) -> usize { let Self(index) = self; - index.into_inner() + index.into_offset() } #[inline(always)] unsafe fn from_index_unchecked(index: usize) -> Self { - Self($crate::utils::PrivateIndex::new(index)) + Self($crate::utils::OffsetProvider::::new(index)) } #[inline] @@ -241,7 +241,7 @@ macro_rules! blazemap_id_inner { $(#[$attrs])* #[derive(Clone, Copy, Eq, PartialEq, Hash)] #[repr(transparent)] - $vis struct $new_type($crate::utils::PrivateIndex); + $vis struct $new_type($crate::utils::OffsetProvider); impl $new_type { @@ -251,7 +251,7 @@ macro_rules! blazemap_id_inner { use $crate::prelude::BlazeMapId; let next_id = Self::static_info().0.next_id(); - Self(unsafe { $crate::utils::PrivateIndex::new(next_id) }) + Self(unsafe { $crate::utils::OffsetProvider::::new(next_id) }) } } @@ -264,12 +264,12 @@ macro_rules! blazemap_id_inner { #[inline] fn get_index(self) -> usize { let Self(index) = self; - index.into_inner() + index.into_offset() } #[inline(always)] unsafe fn from_index_unchecked(index: usize) -> Self { - Self($crate::utils::PrivateIndex::new(index)) + Self($crate::utils::OffsetProvider::::new(index)) } #[inline] @@ -290,7 +290,7 @@ macro_rules! blazemap_id_inner { { let Self(index) = self; f.debug_tuple(::std::stringify!($new_type)) - .field(&index.into_inner()) + .field(&index.into_offset()) .finish() } } @@ -301,7 +301,7 @@ macro_rules! blazemap_id_inner { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { let Self(index) = self; - write!(f, "{}", index.into_inner()) + write!(f, "{}", index.into_offset()) } } } @@ -329,8 +329,8 @@ macro_rules! blazemap_derive_key_inner { let guard = ::static_info().read(); let (lhs, rhs) = unsafe { ( - guard.get_key_unchecked(lhs.into_inner()), - guard.get_key_unchecked(rhs.into_inner()), + guard.get_key_unchecked(lhs.into_offset()), + guard.get_key_unchecked(rhs.into_offset()), ) }; lhs.partial_cmp(rhs) @@ -355,8 +355,8 @@ macro_rules! blazemap_derive_key_inner { let guard = ::static_info().read(); let (lhs, rhs) = unsafe { ( - guard.get_key_unchecked(lhs.into_inner()), - guard.get_key_unchecked(rhs.into_inner()), + guard.get_key_unchecked(lhs.into_offset()), + guard.get_key_unchecked(rhs.into_offset()), ) }; lhs.cmp(rhs) @@ -372,10 +372,10 @@ macro_rules! blazemap_derive_key_inner { let Self(index) = self; let mut f = f.debug_struct(::std::stringify!($new_type)); let guard = ::static_info().read(); - let original_key = unsafe { guard.get_key_unchecked(index.into_inner()) }; + let original_key = unsafe { guard.get_key_unchecked(index.into_offset()) }; f.field("original_key", original_key); drop(guard); - f.field("index", &index.into_inner()).finish() + f.field("index", &index.into_offset()).finish() } } }; @@ -387,7 +387,7 @@ macro_rules! blazemap_derive_key_inner { let Self(index) = self; let guard = ::static_info().read(); - let original_key = unsafe { guard.get_key_unchecked(index.into_inner()) }; + let original_key = unsafe { guard.get_key_unchecked(index.into_offset()) }; write!(f, "{original_key}") } } @@ -420,7 +420,7 @@ macro_rules! blazemap_derive_key_inner { unsafe { ::static_info() .read() - .get_key_unchecked(index.into_inner()) + .get_key_unchecked(index.into_offset()) .serialize(serializer) } } @@ -437,7 +437,7 @@ macro_rules! blazemap_derive_assigned_sn { fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> { let Self(lhs) = self; let Self(rhs) = other; - lhs.into_inner().partial_cmp(&rhs.into_inner()) + lhs.into_offset().partial_cmp(&rhs.into_offset()) } } }; @@ -454,7 +454,7 @@ macro_rules! blazemap_derive_assigned_sn { fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { let Self(lhs) = self; let Self(rhs) = other; - lhs.into_inner().cmp(&rhs.into_inner()) + lhs.into_offset().cmp(&rhs.into_offset()) } } }; @@ -469,7 +469,7 @@ macro_rules! blazemap_id_inner_derive { fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> { let Self(lhs) = self; let Self(rhs) = other; - lhs.into_inner().partial_cmp(&rhs.into_inner()) + lhs.into_offset().partial_cmp(&rhs.into_offset()) } } }; @@ -486,7 +486,7 @@ macro_rules! blazemap_id_inner_derive { fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { let Self(lhs) = self; let Self(rhs) = other; - lhs.into_inner().cmp(&rhs.into_inner()) + lhs.into_offset().cmp(&rhs.into_offset()) } } }; @@ -498,7 +498,7 @@ macro_rules! blazemap_id_inner_derive { S: $crate::external::serde::Serializer, { let Self(index) = self; - index.into_inner().serialize(serializer) + index.into_offset().serialize(serializer) } } }; diff --git a/src/utils.rs b/src/utils.rs index 64f666c..05d7121 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,9 +1,9 @@ pub use { - private_index::PrivateIndex, + offset_provider::OffsetProvider, static_info::{IdWrapperStaticInfo, TrivialIdStaticInfo}, }; #[doc(hidden)] -mod private_index; +mod offset_provider; #[doc(hidden)] mod static_info; diff --git a/src/utils/private_index.rs b/src/utils/offset_provider.rs similarity index 51% rename from src/utils/private_index.rs rename to src/utils/offset_provider.rs index 8e82264..7b8f8f9 100644 --- a/src/utils/private_index.rs +++ b/src/utils/offset_provider.rs @@ -1,5 +1,8 @@ use std::hash::Hash; +use std::num::NonZeroUsize; +/// Holds and provides the `usize` offset. +/// /// Necessary to protect the internal `usize`, which, in the absence of this wrapper, /// would be public in the module calling /// the [`register_blazemap_id_wrapper`](crate::register_blazemap_id_wrapper). @@ -11,35 +14,52 @@ use std::hash::Hash; #[derive(Clone, Copy, Eq, PartialEq, Hash)] #[repr(transparent)] #[doc(hidden)] -pub struct PrivateIndex(usize); +pub struct OffsetProvider(T); -impl PrivateIndex { +impl OffsetProvider { #[inline(always)] - pub unsafe fn new(index: usize) -> Self { - Self(index) + pub unsafe fn new(offset: usize) -> Self { + Self(offset) } #[inline(always)] - pub fn into_inner(self) -> usize { + pub fn into_offset(self) -> usize { self.0 } } +impl OffsetProvider { + #[inline(always)] + pub unsafe fn new(offset: usize) -> Self { + let inner = offset.checked_add(1).expect("usize overflow"); + Self(unsafe { NonZeroUsize::new_unchecked(inner) }) + } + + #[inline(always)] + pub fn into_offset(self) -> usize { + self.0.get() - 1 + } +} + #[cfg(test)] mod tests { use std::fmt::{Debug, Display}; + use std::num::NonZeroUsize; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use static_assertions::assert_not_impl_any; - use crate::utils::private_index::PrivateIndex; + use crate::utils::offset_provider::OffsetProvider; // These assertions are needed in order to prevent standard traits // from being automatically derived for types // generated by the [`register_blazemap_id_wrapper`](crate::register_blazemap_id) macro. - assert_not_impl_any!(PrivateIndex: Default, Debug, Display, PartialOrd); + assert_not_impl_any!(OffsetProvider: Default, Debug, Display, PartialOrd); + assert_not_impl_any!(OffsetProvider: Default, Debug, Display, PartialOrd); #[cfg(feature = "serde")] - assert_not_impl_any!(PrivateIndex: Serialize, Deserialize<'static>); + assert_not_impl_any!(OffsetProvider: Serialize, Deserialize<'static>); + #[cfg(feature = "serde")] + assert_not_impl_any!(OffsetProvider: Serialize, Deserialize<'static>); }