Improve inlining of Dynamic methods.
This commit is contained in:
parent
839738b97e
commit
187824e684
320
src/any.rs
320
src/any.rs
@ -203,6 +203,7 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Map the name of a standard type into a friendly form.
|
/// Map the name of a standard type into a friendly form.
|
||||||
|
#[inline]
|
||||||
pub(crate) fn map_std_type_name(name: &str) -> &str {
|
pub(crate) fn map_std_type_name(name: &str) -> &str {
|
||||||
if name == type_name::<String>() {
|
if name == type_name::<String>() {
|
||||||
"string"
|
"string"
|
||||||
@ -340,30 +341,47 @@ impl Dynamic {
|
|||||||
/// assert_eq!(new_result.type_name(), "string");
|
/// assert_eq!(new_result.type_name(), "string");
|
||||||
/// assert_eq!(new_result.to_string(), "hello");
|
/// assert_eq!(new_result.to_string(), "hello");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
pub fn from<T: Variant + Clone>(value: T) -> Self {
|
pub fn from<T: Variant + Clone>(value: T) -> Self {
|
||||||
if let Some(result) = <dyn Any>::downcast_ref::<()>(&value) {
|
let type_id = TypeId::of::<T>();
|
||||||
return result.clone().into();
|
|
||||||
} else if let Some(result) = <dyn Any>::downcast_ref::<bool>(&value) {
|
|
||||||
return result.clone().into();
|
|
||||||
} else if let Some(result) = <dyn Any>::downcast_ref::<INT>(&value) {
|
|
||||||
return result.clone().into();
|
|
||||||
} else if let Some(result) = <dyn Any>::downcast_ref::<char>(&value) {
|
|
||||||
return result.clone().into();
|
|
||||||
} else if let Some(result) = <dyn Any>::downcast_ref::<ImmutableString>(&value) {
|
|
||||||
return result.clone().into();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if type_id == TypeId::of::<INT>() {
|
||||||
|
return <dyn Any>::downcast_ref::<INT>(&value)
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if let Some(result) = <dyn Any>::downcast_ref::<FLOAT>(&value) {
|
if type_id == TypeId::of::<FLOAT>() {
|
||||||
return result.clone().into();
|
return <dyn Any>::downcast_ref::<FLOAT>(&value)
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<bool>() {
|
||||||
|
return <dyn Any>::downcast_ref::<bool>(&value)
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<char>() {
|
||||||
|
return <dyn Any>::downcast_ref::<char>(&value)
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<ImmutableString>() {
|
||||||
|
return <dyn Any>::downcast_ref::<ImmutableString>(&value)
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<()>() {
|
||||||
|
return ().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut boxed = Box::new(value);
|
let mut boxed = Box::new(value);
|
||||||
|
|
||||||
boxed = match unsafe_cast_box::<_, Dynamic>(boxed) {
|
|
||||||
Ok(d) => return *d,
|
|
||||||
Err(val) => val,
|
|
||||||
};
|
|
||||||
boxed = match unsafe_cast_box::<_, String>(boxed) {
|
boxed = match unsafe_cast_box::<_, String>(boxed) {
|
||||||
Ok(s) => return (*s).into(),
|
Ok(s) => return (*s).into(),
|
||||||
Err(val) => val,
|
Err(val) => val,
|
||||||
@ -384,6 +402,11 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxed = match unsafe_cast_box::<_, Dynamic>(boxed) {
|
||||||
|
Ok(d) => return *d,
|
||||||
|
Err(val) => val,
|
||||||
|
};
|
||||||
|
|
||||||
Self(Union::Variant(Box::new(boxed)))
|
Self(Union::Variant(Box::new(boxed)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,30 +424,80 @@ impl Dynamic {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(x.try_cast::<u32>().unwrap(), 42);
|
/// assert_eq!(x.try_cast::<u32>().unwrap(), 42);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
pub fn try_cast<T: Variant>(self) -> Option<T> {
|
pub fn try_cast<T: Variant>(self) -> Option<T> {
|
||||||
let type_id = TypeId::of::<T>();
|
let type_id = TypeId::of::<T>();
|
||||||
|
|
||||||
|
if type_id == TypeId::of::<INT>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Int(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
if type_id == TypeId::of::<FLOAT>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Float(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<bool>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Bool(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<ImmutableString>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Str(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<String>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Str(value) => unsafe_try_cast(value.into_owned()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<char>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Char(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
if type_id == TypeId::of::<Array>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Array(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
if type_id == TypeId::of::<Map>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Map(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<FnPtr>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::FnPtr(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<()>() {
|
||||||
|
return match self.0 {
|
||||||
|
Union::Unit(value) => unsafe_try_cast(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
if type_id == TypeId::of::<Dynamic>() {
|
if type_id == TypeId::of::<Dynamic>() {
|
||||||
return unsafe_cast_box::<_, T>(Box::new(self)).ok().map(|v| *v);
|
return unsafe_cast_box::<_, T>(Box::new(self)).ok().map(|v| *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(value) => unsafe_try_cast(value),
|
|
||||||
Union::Bool(value) => unsafe_try_cast(value),
|
|
||||||
Union::Str(value) if type_id == TypeId::of::<ImmutableString>() => {
|
|
||||||
unsafe_try_cast(value)
|
|
||||||
}
|
|
||||||
Union::Str(value) => unsafe_try_cast(value.into_owned()),
|
|
||||||
Union::Char(value) => unsafe_try_cast(value),
|
|
||||||
Union::Int(value) => unsafe_try_cast(value),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
Union::Float(value) => unsafe_try_cast(value),
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
Union::Array(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
Union::Map(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
|
||||||
Union::FnPtr(value) => unsafe_try_cast(value),
|
|
||||||
Union::Variant(value) => (*value).as_box_any().downcast().map(|x| *x).ok(),
|
Union::Variant(value) => (*value).as_box_any().downcast().map(|x| *x).ok(),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,81 +517,162 @@ impl Dynamic {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(x.cast::<u32>(), 42);
|
/// assert_eq!(x.cast::<u32>(), 42);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
pub fn cast<T: Variant + Clone>(self) -> T {
|
pub fn cast<T: Variant + Clone>(self) -> T {
|
||||||
let type_id = TypeId::of::<T>();
|
self.try_cast::<T>().unwrap()
|
||||||
|
|
||||||
if type_id == TypeId::of::<Dynamic>() {
|
|
||||||
return *unsafe_cast_box::<_, T>(Box::new(self)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.0 {
|
|
||||||
Union::Unit(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
Union::Bool(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
Union::Str(value) if type_id == TypeId::of::<ImmutableString>() => {
|
|
||||||
unsafe_try_cast(value).unwrap()
|
|
||||||
}
|
|
||||||
Union::Str(value) => unsafe_try_cast(value.into_owned()).unwrap(),
|
|
||||||
Union::Char(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
Union::Int(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
Union::Float(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
Union::Array(value) => *unsafe_cast_box::<_, T>(value).unwrap(),
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
Union::Map(value) => *unsafe_cast_box::<_, T>(value).unwrap(),
|
|
||||||
Union::FnPtr(value) => unsafe_try_cast(value).unwrap(),
|
|
||||||
Union::Variant(value) => (*value).as_box_any().downcast().map(|x| *x).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference of a specific type to the `Dynamic`.
|
/// Get a reference of a specific type to the `Dynamic`.
|
||||||
/// Casting to `Dynamic` just returns a reference to it.
|
/// Casting to `Dynamic` just returns a reference to it.
|
||||||
/// Returns `None` if the cast fails.
|
/// Returns `None` if the cast fails.
|
||||||
|
#[inline(always)]
|
||||||
pub fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> {
|
pub fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> {
|
||||||
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
let type_id = TypeId::of::<T>();
|
||||||
|
|
||||||
|
if type_id == TypeId::of::<INT>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Int(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
if type_id == TypeId::of::<FLOAT>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Float(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<bool>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Bool(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<ImmutableString>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<String>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<char>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Char(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
if type_id == TypeId::of::<Array>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Array(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
if type_id == TypeId::of::<Map>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Map(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<FnPtr>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::FnPtr(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<()>() {
|
||||||
|
return match &self.0 {
|
||||||
|
Union::Unit(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_ref::<T>(self);
|
return <dyn Any>::downcast_ref::<T>(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Union::Unit(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
Union::Bool(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value)
|
|
||||||
.or_else(|| <dyn Any>::downcast_ref::<T>(value.as_ref())),
|
|
||||||
Union::Char(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
Union::Int(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
Union::Float(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
Union::Array(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
Union::Map(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
|
||||||
Union::FnPtr(value) => <dyn Any>::downcast_ref::<T>(value),
|
|
||||||
Union::Variant(value) => value.as_ref().as_ref().as_any().downcast_ref::<T>(),
|
Union::Variant(value) => value.as_ref().as_ref().as_any().downcast_ref::<T>(),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference of a specific type to the `Dynamic`.
|
/// Get a mutable reference of a specific type to the `Dynamic`.
|
||||||
/// Casting to `Dynamic` just returns a mutable reference to it.
|
/// Casting to `Dynamic` just returns a mutable reference to it.
|
||||||
/// Returns `None` if the cast fails.
|
/// Returns `None` if the cast fails.
|
||||||
|
#[inline(always)]
|
||||||
pub fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> {
|
pub fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> {
|
||||||
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
let type_id = TypeId::of::<T>();
|
||||||
|
|
||||||
|
if type_id == TypeId::of::<INT>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Int(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
if type_id == TypeId::of::<FLOAT>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Float(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<bool>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Bool(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<ImmutableString>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Str(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<char>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Char(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
if type_id == TypeId::of::<Array>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Array(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
if type_id == TypeId::of::<Map>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Map(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<FnPtr>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::FnPtr(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<()>() {
|
||||||
|
return match &mut self.0 {
|
||||||
|
Union::Unit(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if type_id == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_mut::<T>(self);
|
return <dyn Any>::downcast_mut::<T>(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
Union::Unit(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
Union::Bool(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
Union::Str(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
Union::Char(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
Union::Int(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
Union::Float(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
Union::Array(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
Union::Map(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
|
||||||
Union::FnPtr(value) => <dyn Any>::downcast_mut::<T>(value),
|
|
||||||
Union::Variant(value) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Variant(value) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ use crate::stdlib::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Cast a type into another type.
|
/// Cast a type into another type.
|
||||||
|
#[inline(always)]
|
||||||
pub fn unsafe_try_cast<A: Any, B: Any>(a: A) -> Option<B> {
|
pub fn unsafe_try_cast<A: Any, B: Any>(a: A) -> Option<B> {
|
||||||
if TypeId::of::<B>() == a.type_id() {
|
if TypeId::of::<B>() == a.type_id() {
|
||||||
// SAFETY: Just checked we have the right type. We explicitly forget the
|
// SAFETY: Just checked we have the right type. We explicitly forget the
|
||||||
@ -28,6 +29,7 @@ pub fn unsafe_try_cast<A: Any, B: Any>(a: A) -> Option<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cast a Boxed type into another type.
|
/// Cast a Boxed type into another type.
|
||||||
|
#[inline(always)]
|
||||||
pub fn unsafe_cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<Box<T>, Box<X>> {
|
pub fn unsafe_cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<Box<T>, Box<X>> {
|
||||||
// Only allow casting to the exact same type
|
// Only allow casting to the exact same type
|
||||||
if TypeId::of::<X>() == TypeId::of::<T>() {
|
if TypeId::of::<X>() == TypeId::of::<T>() {
|
||||||
@ -51,6 +53,7 @@ pub fn unsafe_cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<Box<T>, B
|
|||||||
///
|
///
|
||||||
/// Force-casting a local variable's lifetime to the current `Scope`'s larger lifetime saves
|
/// Force-casting a local variable's lifetime to the current `Scope`'s larger lifetime saves
|
||||||
/// on allocations and string cloning, thus avoids us having to maintain a chain of `Scope`'s.
|
/// on allocations and string cloning, thus avoids us having to maintain a chain of `Scope`'s.
|
||||||
|
#[inline]
|
||||||
pub fn unsafe_cast_var_name_to_lifetime<'s>(name: &str, state: &State) -> Cow<'s, str> {
|
pub fn unsafe_cast_var_name_to_lifetime<'s>(name: &str, state: &State) -> Cow<'s, str> {
|
||||||
// If not at global level, we can force-cast
|
// If not at global level, we can force-cast
|
||||||
if state.scope_level > 0 {
|
if state.scope_level > 0 {
|
||||||
|
26
src/utils.rs
26
src/utils.rs
@ -36,11 +36,9 @@ use ahash::AHasher;
|
|||||||
pub struct StraightHasher(u64);
|
pub struct StraightHasher(u64);
|
||||||
|
|
||||||
impl Hasher for StraightHasher {
|
impl Hasher for StraightHasher {
|
||||||
#[inline(always)]
|
|
||||||
fn finish(&self) -> u64 {
|
fn finish(&self) -> u64 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
fn write(&mut self, bytes: &[u8]) {
|
fn write(&mut self, bytes: &[u8]) {
|
||||||
let mut key = [0_u8; 8];
|
let mut key = [0_u8; 8];
|
||||||
key.copy_from_slice(&bytes[..8]); // Panics if fewer than 8 bytes
|
key.copy_from_slice(&bytes[..8]); // Panics if fewer than 8 bytes
|
||||||
@ -50,7 +48,6 @@ impl Hasher for StraightHasher {
|
|||||||
|
|
||||||
impl StraightHasher {
|
impl StraightHasher {
|
||||||
/// Create a `StraightHasher`.
|
/// Create a `StraightHasher`.
|
||||||
#[inline(always)]
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(0)
|
Self(0)
|
||||||
}
|
}
|
||||||
@ -63,7 +60,6 @@ pub struct StraightHasherBuilder;
|
|||||||
impl BuildHasher for StraightHasherBuilder {
|
impl BuildHasher for StraightHasherBuilder {
|
||||||
type Hasher = StraightHasher;
|
type Hasher = StraightHasher;
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn build_hasher(&self) -> Self::Hasher {
|
fn build_hasher(&self) -> Self::Hasher {
|
||||||
StraightHasher::new()
|
StraightHasher::new()
|
||||||
}
|
}
|
||||||
@ -150,7 +146,6 @@ pub struct StaticVec<T> {
|
|||||||
const MAX_STATIC_VEC: usize = 4;
|
const MAX_STATIC_VEC: usize = 4;
|
||||||
|
|
||||||
impl<T> Drop for StaticVec<T> {
|
impl<T> Drop for StaticVec<T> {
|
||||||
#[inline(always)]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.clear();
|
self.clear();
|
||||||
}
|
}
|
||||||
@ -233,7 +228,6 @@ impl<T: 'static> IntoIterator for StaticVec<T> {
|
|||||||
|
|
||||||
impl<T> StaticVec<T> {
|
impl<T> StaticVec<T> {
|
||||||
/// Create a new `StaticVec`.
|
/// Create a new `StaticVec`.
|
||||||
#[inline(always)]
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
@ -249,7 +243,6 @@ impl<T> StaticVec<T> {
|
|||||||
self.len = 0;
|
self.len = 0;
|
||||||
}
|
}
|
||||||
/// Extract a `MaybeUninit` into a concrete initialized type.
|
/// Extract a `MaybeUninit` into a concrete initialized type.
|
||||||
#[inline(always)]
|
|
||||||
fn extract(value: MaybeUninit<T>) -> T {
|
fn extract(value: MaybeUninit<T>) -> T {
|
||||||
unsafe { value.assume_init() }
|
unsafe { value.assume_init() }
|
||||||
}
|
}
|
||||||
@ -311,7 +304,6 @@ impl<T> StaticVec<T> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
/// Is data stored in fixed-size storage?
|
/// Is data stored in fixed-size storage?
|
||||||
#[inline(always)]
|
|
||||||
fn is_fixed_storage(&self) -> bool {
|
fn is_fixed_storage(&self) -> bool {
|
||||||
self.len <= MAX_STATIC_VEC
|
self.len <= MAX_STATIC_VEC
|
||||||
}
|
}
|
||||||
@ -418,12 +410,10 @@ impl<T> StaticVec<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the number of items in this `StaticVec`.
|
/// Get the number of items in this `StaticVec`.
|
||||||
#[inline(always)]
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.len
|
self.len
|
||||||
}
|
}
|
||||||
/// Is this `StaticVec` empty?
|
/// Is this `StaticVec` empty?
|
||||||
#[inline(always)]
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len == 0
|
self.len == 0
|
||||||
}
|
}
|
||||||
@ -664,48 +654,41 @@ pub struct ImmutableString(Shared<String>);
|
|||||||
impl Deref for ImmutableString {
|
impl Deref for ImmutableString {
|
||||||
type Target = String;
|
type Target = String;
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<String> for ImmutableString {
|
impl AsRef<String> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn as_ref(&self) -> &String {
|
fn as_ref(&self) -> &String {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<str> for ImmutableString {
|
impl Borrow<str> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn borrow(&self) -> &str {
|
fn borrow(&self) -> &str {
|
||||||
self.0.as_str()
|
self.0.as_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for ImmutableString {
|
impl From<&str> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from(value: &str) -> Self {
|
fn from(value: &str) -> Self {
|
||||||
Self(value.to_string().into())
|
Self(value.to_string().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<String> for ImmutableString {
|
impl From<String> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from(value: String) -> Self {
|
fn from(value: String) -> Self {
|
||||||
Self(value.into())
|
Self(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Box<String>> for ImmutableString {
|
impl From<Box<String>> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from(value: Box<String>) -> Self {
|
fn from(value: Box<String>) -> Self {
|
||||||
Self(value.into())
|
Self(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ImmutableString> for String {
|
impl From<ImmutableString> for String {
|
||||||
#[inline(always)]
|
|
||||||
fn from(value: ImmutableString) -> Self {
|
fn from(value: ImmutableString) -> Self {
|
||||||
value.into_owned()
|
value.into_owned()
|
||||||
}
|
}
|
||||||
@ -714,49 +697,42 @@ impl From<ImmutableString> for String {
|
|||||||
impl FromStr for ImmutableString {
|
impl FromStr for ImmutableString {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Ok(Self(s.to_string().into()))
|
Ok(Self(s.to_string().into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromIterator<char> for ImmutableString {
|
impl FromIterator<char> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
|
||||||
Self(iter.into_iter().collect::<String>().into())
|
Self(iter.into_iter().collect::<String>().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromIterator<&'a char> for ImmutableString {
|
impl<'a> FromIterator<&'a char> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
|
||||||
Self(iter.into_iter().cloned().collect::<String>().into())
|
Self(iter.into_iter().cloned().collect::<String>().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromIterator<&'a str> for ImmutableString {
|
impl<'a> FromIterator<&'a str> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
|
||||||
Self(iter.into_iter().collect::<String>().into())
|
Self(iter.into_iter().collect::<String>().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromIterator<String> for ImmutableString {
|
impl<'a> FromIterator<String> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
|
||||||
Self(iter.into_iter().collect::<String>().into())
|
Self(iter.into_iter().collect::<String>().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ImmutableString {
|
impl fmt::Display for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(self.0.as_str(), f)
|
fmt::Display::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ImmutableString {
|
impl fmt::Debug for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Debug::fmt(self.0.as_str(), f)
|
fmt::Debug::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
@ -891,7 +867,6 @@ impl Add<char> for &ImmutableString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AddAssign<char> for ImmutableString {
|
impl AddAssign<char> for ImmutableString {
|
||||||
#[inline(always)]
|
|
||||||
fn add_assign(&mut self, rhs: char) {
|
fn add_assign(&mut self, rhs: char) {
|
||||||
self.make_mut().push(rhs);
|
self.make_mut().push(rhs);
|
||||||
}
|
}
|
||||||
@ -906,7 +881,6 @@ impl ImmutableString {
|
|||||||
}
|
}
|
||||||
/// Make sure that the `ImmutableString` is unique (i.e. no other outstanding references).
|
/// Make sure that the `ImmutableString` is unique (i.e. no other outstanding references).
|
||||||
/// Then return a mutable reference to the `String`.
|
/// Then return a mutable reference to the `String`.
|
||||||
#[inline(always)]
|
|
||||||
pub fn make_mut(&mut self) -> &mut String {
|
pub fn make_mut(&mut self) -> &mut String {
|
||||||
shared_make_mut(&mut self.0)
|
shared_make_mut(&mut self.0)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user