start primitive newtypes

Signed-off-by: Avril <flanchan@cumallover.me>
master
Avril 4 years ago
parent 6c3e9776a5
commit 21e3f37cf2
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -10,6 +10,7 @@ edition = "2018"
license = "MIT" license = "MIT"
[dependencies] [dependencies]
const_fn = "0.4.4"
serde = {version = "1.0.116", features = ["derive"], optional = true} serde = {version = "1.0.116", features = ["derive"], optional = true}
[dev-dependencies] [dev-dependencies]

@ -32,6 +32,8 @@
#![cfg_attr(nightly, feature(const_fn))] #![cfg_attr(nightly, feature(const_fn))]
#[cfg(nightly)] extern crate test; #[cfg(nightly)] extern crate test;
#[macro_use] extern crate const_fn;
const MAX: usize = 256; const MAX: usize = 256;
@ -42,8 +44,14 @@ use iter::*;
pub mod entry; pub mod entry;
pub use entry::Entry; pub use entry::Entry;
pub mod primitive;
mod init; mod init;
mod private {
pub trait Sealed{}
}
/// A helper macro for creating `Map` instances with or without pre-set entries. /// A helper macro for creating `Map` instances with or without pre-set entries.
/// ///
/// # Create empty map /// # Create empty map

@ -0,0 +1,135 @@
//! Contains `Collapse` impls for primitive types through a newtime wrapper.
//!
//! Such wrappers are a workaround for the lack of template specialisation available in Rust so far, as the generic `impl<T: Hash> Collapse<T> for T` still requires computing the hash of the internal types before reducing to the `u8` page index.
//! For primitive types, this is unnessisary and causes a (very slight) performance loss.
use super::*;
use std::num::*;
pub trait PrimitiveCollapse: private::Sealed
{
fn collapse(&self) -> u8;
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Default, Ord, PartialOrd)]
pub struct Primitive<T>(T);
impl<T: PrimitiveCollapse+ Eq> Collapse for Primitive<T>
{
#[inline(always)] fn collapse(&self) -> u8 {
self.0.collapse()
}
}
impl<T: PrimitiveCollapse+ Eq> Primitive<T>
{
#[const_fn]
#[inline] pub const fn new(value: T) -> Self
{
Self(value)
}
#[inline] pub fn into_inner(self) -> T
{
self.0
}
#[const_fn]
#[inline] pub fn inner(&self) -> &T
{
&self.0
}
#[inline] pub fn inner_mut(&mut self) -> &mut T
{
&mut self.0
}
#[const_fn]
#[inline] pub const fn copy_into_inner(&self) -> T
where T: Copy
{
self.0
}
}
macro_rules! prim {
($name:ty) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
#[inline(always)] fn collapse(&self) -> u8 {
(*self) as u8
}
}
};
($name:ty: +) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
#[inline(always)] fn collapse(&self) -> u8 {
self.get() as u8
}
}
};
($name:ty: ^) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
#[inline(always)] fn collapse(&self) -> u8 {
super::collapse(<$name>::to_ne_bytes(*self))
}
}
};
($name:ty: ^+) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
#[inline(always)] fn collapse(&self) -> u8 {
super::collapse(self.get().to_ne_bytes())
}
}
};
($name:ty: fn {$($block:tt)*}) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
#[inline(always)] fn collapse(&self) -> u8 {
$($block)+
}
}
};
($name:ty: {$($block:tt)*}) => {
impl private::Sealed for $name{}
impl PrimitiveCollapse for $name
{
$($block)+
}
};
}
prim!(u8);
prim!(i8);
prim!(u16: ^);
prim!(i16: ^);
prim!(u32: ^);
prim!(i32: ^);
prim!(u64: ^);
prim!(i64: ^);
prim!(u128: ^);
prim!(i128: ^);
prim!(isize: ^);
prim!(usize: ^);
prim!(NonZeroU8: +);
prim!(NonZeroI8: +);
prim!(NonZeroU16: ^+);
prim!(NonZeroI16: ^+);
prim!(NonZeroU32: ^+);
prim!(NonZeroI32: ^+);
prim!(NonZeroU64: ^+);
prim!(NonZeroI64: ^+);
prim!(NonZeroU128: ^+);
prim!(NonZeroI128: ^+);
prim!(NonZeroIsize: ^+);
prim!(NonZeroUsize: ^+);
prim!((): fn {
0
});
Loading…
Cancel
Save