Skip to content

Commit

Permalink
Merge pull request #55 from GrigorenkoPV/inline
Browse files Browse the repository at this point in the history
sparkle some #[inline]
  • Loading branch information
droundy authored Jul 27, 2024
2 parents fc5ad70 + fd682be commit 8a5feb3
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub struct ArcIntern<T: ?Sized + Eq + Hash + Send + Sync + 'static> {

#[cfg(feature = "deepsize")]
impl<T: ?Sized + Eq + Hash + Send + Sync + 'static> deepsize::DeepSizeOf for ArcIntern<T> {
#[inline(always)]
fn deep_size_of_children(&self, _context: &mut deepsize::Context) -> usize {
0
}
Expand Down Expand Up @@ -82,11 +83,13 @@ pub(crate) struct RefCount<T: ?Sized> {

impl<T: ?Sized + Eq> Eq for RefCount<T> {}
impl<T: ?Sized + PartialEq> PartialEq for RefCount<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.data == other.data
}
}
impl<T: ?Sized + Hash> Hash for RefCount<T> {
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.data.hash(hasher)
}
Expand All @@ -95,35 +98,41 @@ impl<T: ?Sized + Hash> Hash for RefCount<T> {
#[derive(Eq, PartialEq)]
pub(crate) struct BoxRefCount<T: ?Sized>(pub Box<RefCount<T>>);
impl<T: ?Sized + Hash> Hash for BoxRefCount<T> {
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.0.data.hash(hasher)
}
}

impl<T> BoxRefCount<T> {
#[inline(always)]
fn into_inner(self) -> T {
self.0.data
}
}

impl<T: ?Sized> Borrow<T> for BoxRefCount<T> {
#[inline(always)]
fn borrow(&self) -> &T {
&self.0.data
}
}
impl<T: ?Sized> Borrow<RefCount<T>> for BoxRefCount<T> {
#[inline(always)]
fn borrow(&self) -> &RefCount<T> {
&self.0
}
}
impl<T: ?Sized> Deref for BoxRefCount<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0.data
}
}

impl<T: ?Sized + Eq + Hash + Send + Sync + 'static> ArcIntern<T> {
#[inline(always)]
fn get_pointer(&self) -> *const RefCount<T> {
self.pointer.as_ptr()
}
Expand Down Expand Up @@ -302,6 +311,7 @@ impl<T: ?Sized + Eq + Hash + Send + Sync> Drop for ArcIntern<T> {
}

impl<T: ?Sized + Send + Sync + Hash + Eq> AsRef<T> for ArcIntern<T> {
#[inline(always)]
fn as_ref(&self) -> &T {
unsafe { &self.pointer.as_ref().data }
}
Expand All @@ -326,18 +336,21 @@ impl_as_ref!(Path => OsStr);

impl<T: ?Sized + Eq + Hash + Send + Sync> Deref for ArcIntern<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
self.as_ref()
}
}

impl<T: ?Sized + Eq + Hash + Send + Sync + Display> Display for ArcIntern<T> {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
self.deref().fmt(f)
}
}

impl<T: ?Sized + Eq + Hash + Send + Sync> Pointer for ArcIntern<T> {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
Pointer::fmt(&self.get_pointer(), f)
}
Expand All @@ -349,36 +362,44 @@ impl<T: ?Sized + Eq + Hash + Send + Sync> Pointer for ArcIntern<T> {
/// value, but it *is* observable, since you could compare the
/// hash of the pointer with hash of the data itself.
impl<T: ?Sized + Eq + Hash + Send + Sync> Hash for ArcIntern<T> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.get_pointer().hash(state);
}
}

impl<T: ?Sized + Eq + Hash + Send + Sync> PartialEq for ArcIntern<T> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
std::ptr::eq(self.get_pointer(), other.get_pointer())
}
}
impl<T: ?Sized + Eq + Hash + Send + Sync> Eq for ArcIntern<T> {}

impl<T: ?Sized + Eq + Hash + Send + Sync + PartialOrd> PartialOrd for ArcIntern<T> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_ref().partial_cmp(other)
}
#[inline]
fn lt(&self, other: &Self) -> bool {
self.as_ref().lt(other)
}
#[inline]
fn le(&self, other: &Self) -> bool {
self.as_ref().le(other)
}
#[inline]
fn gt(&self, other: &Self) -> bool {
self.as_ref().gt(other)
}
#[inline]
fn ge(&self, other: &Self) -> bool {
self.as_ref().ge(other)
}
}
impl<T: ?Sized + Eq + Hash + Send + Sync + Ord> Ord for ArcIntern<T> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_ref().cmp(other)
}
Expand All @@ -387,18 +408,21 @@ impl<T: ?Sized + Eq + Hash + Send + Sync + Ord> Ord for ArcIntern<T> {
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
#[cfg(feature = "serde")]
impl<T: ?Sized + Eq + Hash + Send + Sync + Serialize> Serialize for ArcIntern<T> {
#[inline]
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}

impl<T: Eq + Hash + Send + Sync + 'static> From<T> for ArcIntern<T> {
#[inline]
fn from(t: T) -> Self {
ArcIntern::new(t)
}
}

impl<T: Eq + Hash + Send + Sync + Default + 'static> Default for ArcIntern<T> {
#[inline]
fn default() -> Self {
ArcIntern::new(Default::default())
}
Expand All @@ -410,6 +434,7 @@ impl<'de, T> Deserialize<'de> for ArcIntern<T>
where
T: Eq + Hash + Send + Sync + 'static + Deserialize<'de>,
{
#[inline]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
T::deserialize(deserializer).map(|x: T| Self::new(x))
}
Expand Down
26 changes: 26 additions & 0 deletions src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl<'a, T: ?Sized + deepsize::DeepSizeOf> deepsize::DeepSizeOf for ArenaIntern<
}

impl<'a, T: ?Sized> Clone for ArenaIntern<'a, T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
Expand All @@ -72,6 +73,7 @@ impl<'a, T: ?Sized> Copy for ArenaIntern<'a, T> {}

impl<T: ?Sized> Arena<T> {
/// Allocate a new `Arena`
#[inline]
pub fn new() -> Self {
Arena {
data: Mutex::new(HashSet::new()),
Expand Down Expand Up @@ -148,6 +150,7 @@ impl Arena<str> {
/// If this value has not previously been interned, then `intern` will
/// allocate a spot for the value on the heap. Otherwise, it will return a
/// pointer to the `str` previously allocated.
#[inline]
pub fn intern<'a>(&'a self, val: &str) -> ArenaIntern<'a, str> {
self.intern_ref(val)
}
Expand All @@ -156,6 +159,7 @@ impl Arena<str> {
/// If this value has not previously been interned, then `intern` will save
/// the provided `String`. Otherwise, it will free its input `String` and
/// return a pointer to the `str` previously saved.
#[inline]
pub fn intern_string(&self, val: String) -> ArenaIntern<str> {
self.intern_from_owned(val)
}
Expand All @@ -164,6 +168,7 @@ impl Arena<str> {
/// If this value has not previously been interned, then `intern` will save
/// the provided `Box<str>`. Otherwise, it will free its input `Box<str>`
/// and return a pointer to the `str` previously saved.
#[inline]
pub fn intern_box(&self, val: Box<str>) -> ArenaIntern<str> {
self.intern_from_owned(val)
}
Expand All @@ -183,6 +188,7 @@ impl Arena<std::ffi::CStr> {
/// let y = arena.intern(std::ffi::CString::new("hello").unwrap().as_c_str());
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern<'a>(&'a self, val: &std::ffi::CStr) -> ArenaIntern<'a, std::ffi::CStr> {
self.intern_ref(val)
}
Expand All @@ -200,6 +206,7 @@ impl Arena<std::ffi::CStr> {
/// let y = arena.intern_cstring(std::ffi::CString::new("hello").unwrap());
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_cstring(&self, val: std::ffi::CString) -> ArenaIntern<std::ffi::CStr> {
self.intern_from_owned(val)
}
Expand All @@ -217,6 +224,7 @@ impl Arena<std::ffi::CStr> {
/// let y = arena.intern_box(std::ffi::CString::new("hello").unwrap().into_boxed_c_str());
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_box(&self, val: Box<std::ffi::CStr>) -> ArenaIntern<std::ffi::CStr> {
self.intern_from_owned(val)
}
Expand All @@ -236,6 +244,7 @@ impl Arena<std::ffi::OsStr> {
/// let y = arena.intern(std::ffi::OsStr::new("hello"));
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern<'a>(&'a self, val: &std::ffi::OsStr) -> ArenaIntern<'a, std::ffi::OsStr> {
self.intern_ref(val)
}
Expand All @@ -253,6 +262,7 @@ impl Arena<std::ffi::OsStr> {
/// let y = arena.intern_osstring(std::ffi::OsString::from("hello"));
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_osstring(&self, val: std::ffi::OsString) -> ArenaIntern<std::ffi::OsStr> {
self.intern_from_owned(val)
}
Expand All @@ -270,6 +280,7 @@ impl Arena<std::ffi::OsStr> {
/// let y = arena.intern_box(std::ffi::OsString::from("hello").into_boxed_os_str());
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_box(&self, val: Box<std::ffi::OsStr>) -> ArenaIntern<std::ffi::OsStr> {
self.intern_from_owned(val)
}
Expand All @@ -289,6 +300,7 @@ impl Arena<std::path::Path> {
/// let y = arena.intern(std::path::Path::new("hello"));
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern<'a>(&'a self, val: &std::path::Path) -> ArenaIntern<'a, std::path::Path> {
self.intern_ref(val)
}
Expand All @@ -306,6 +318,7 @@ impl Arena<std::path::Path> {
/// let y = arena.intern_pathbuf(std::path::PathBuf::from("hello"));
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_pathbuf(&self, val: std::path::PathBuf) -> ArenaIntern<std::path::Path> {
self.intern_from_owned(val)
}
Expand All @@ -323,6 +336,7 @@ impl Arena<std::path::Path> {
/// let y = arena.intern_box(std::path::PathBuf::from("hello").into_boxed_path());
/// assert_eq!(x, y);
/// ```
#[inline]
pub fn intern_box(&self, val: Box<std::path::Path>) -> ArenaIntern<std::path::Path> {
self.intern_from_owned(val)
}
Expand All @@ -333,6 +347,7 @@ impl<T: Eq + Hash + Copy> Arena<[T]> {
/// If this value has not previously been interned, then `intern` will
/// allocate a spot for the value on the heap. Otherwise, it will return a
/// pointer to the `[T]` previously allocated.
#[inline]
pub fn intern<'a>(&'a self, val: &[T]) -> ArenaIntern<'a, [T]> {
self.intern_ref(val)
}
Expand All @@ -341,6 +356,7 @@ impl<T: Eq + Hash + Copy> Arena<[T]> {
/// If this value has not previously been interned, then `intern` will save
/// the provided `Vec<T>`. Otherwise, it will free its input `Vec<T>` and
/// return a pointer to the `[T]` previously saved.
#[inline]
pub fn intern_vec(&self, val: Vec<T>) -> ArenaIntern<[T]> {
self.intern_from_owned(val)
}
Expand All @@ -349,6 +365,7 @@ impl<T: Eq + Hash + Copy> Arena<[T]> {
/// If this value has not previously been interned, then `intern` will save
/// the provided `Box<CSr>`. Otherwise, it will free its input `Box<[T]>`
/// and return a pointer to the `[T]` previously saved.
#[inline]
pub fn intern_box(&self, val: Box<[T]>) -> ArenaIntern<[T]> {
self.intern_from_owned(val)
}
Expand Down Expand Up @@ -377,25 +394,29 @@ impl<T: Eq + Hash + ?Sized> Arena<T> {
}

impl<T> Default for Arena<T> {
#[inline]
fn default() -> Self {
Self::new()
}
}

impl<'a, T: ?Sized> AsRef<T> for ArenaIntern<'a, T> {
#[inline(always)]
fn as_ref(&self) -> &T {
self.pointer
}
}

impl<'a, T: ?Sized> std::ops::Deref for ArenaIntern<'a, T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}

impl<'a, T: ?Sized> ArenaIntern<'a, T> {
#[inline(always)]
fn get_pointer(&self) -> *const T {
self.pointer as *const T
}
Expand Down Expand Up @@ -454,6 +475,7 @@ impl<'a, T: ?Sized> ArenaIntern<'a, T> {
/// }
/// }
/// ```
#[inline(always)]
pub fn into_ref(self) -> &'a T {
self.pointer
}
Expand All @@ -465,12 +487,14 @@ impl<'a, T: ?Sized> ArenaIntern<'a, T> {
/// value, but it *is* observable, since you could compare the
/// hash of the pointer with hash of the data itself.
impl<'a, T: ?Sized> Hash for ArenaIntern<'a, T> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.get_pointer().hash(state);
}
}

impl<'a, T: ?Sized> PartialEq for ArenaIntern<'a, T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
std::ptr::eq(self.get_pointer(), other.get_pointer())
}
Expand All @@ -481,12 +505,14 @@ impl<'a, T: ?Sized> Eq for ArenaIntern<'a, T> {}
// create_impls_no_new!(ArenaIntern, arenaintern_impl_tests, ['a], [Eq, Hash], [Eq, Hash]);

impl<'a, T: std::fmt::Debug + ?Sized> std::fmt::Debug for ArenaIntern<'a, T> {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
self.as_ref().fmt(f)
}
}

impl<'a, T: std::fmt::Display + ?Sized> std::fmt::Display for ArenaIntern<'a, T> {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
self.as_ref().fmt(f)
}
Expand Down
Loading

0 comments on commit 8a5feb3

Please sign in to comment.