Skip to content

Instantly share code, notes, and snippets.

@xacrimon
Created October 3, 2021 09:33
Show Gist options
  • Save xacrimon/8327d64267dbf66dbdcc934345664a51 to your computer and use it in GitHub Desktop.
Save xacrimon/8327d64267dbf66dbdcc934345664a51 to your computer and use it in GitHub Desktop.
use std::{
alloc::Layout,
any::TypeId,
cmp::Ordering,
hash::{Hash, Hasher},
mem,
ptr,
};
#[derive(Debug, Copy, Clone, Eq)]
pub struct TypeInfo {
id: TypeId,
layout: Layout,
drop: unsafe fn(*mut u8),
}
impl TypeInfo {
pub const fn of<T: 'static>() -> Self {
unsafe fn drop_ptr<T>(x: *mut u8) {
x.cast::<T>().drop_in_place()
}
Self {
id: TypeId::of::<T>(),
layout: Layout::new::<T>(),
drop: drop_ptr::<T>,
}
}
pub fn id(&self) -> TypeId {
self.id
}
pub fn layout(&self) -> Layout {
self.layout
}
pub unsafe fn drop(&self, data: *mut u8) {
(self.drop)(data);
}
const fn const_less(&self, other: &Self) -> bool {
unsafe {
let a = mem::transmute::<_, u64>(self.id);
let b = mem::transmute::<_, u64>(other.id);
b < a
}
}
}
impl PartialEq for TypeInfo {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl PartialOrd for TypeInfo {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.id.partial_cmp(&other.id)
}
}
impl Ord for TypeInfo {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl Hash for TypeInfo {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.id.hash(state);
}
}
const fn sorted_types<const N: usize>(mut arr: [TypeInfo; N]) -> [TypeInfo; N] {
let mut i = 1;
loop {
let mut j = i;
while j > 0 && arr[j].const_less(&arr[j - 1]) {
unsafe {
let pa = ptr::addr_of_mut!(arr[j]);
let pb = ptr::addr_of_mut!(arr[j - 1]);
ptr::swap(pa, pb);
}
j = j - 1;
}
i += 1;
if i == arr.len() {
break;
}
}
arr
}
pub trait Component: 'static {}
impl<T> Component for T where T: 'static {}
pub trait Bundle {
const COMPONENT_INFO: &'static [TypeInfo];
}
impl<A> Bundle for (A,)
where
A: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([TypeInfo::of::<A>()]);
}
impl<A, B> Bundle for (A, B)
where
A: Component,
B: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] =
&sorted_types([TypeInfo::of::<A>(), TypeInfo::of::<B>()]);
}
impl<A, B, C> Bundle for (A, B, C)
where
A: Component,
B: Component,
C: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
]);
}
impl<A, B, C, D> Bundle for (A, B, C, D)
where
A: Component,
B: Component,
C: Component,
D: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
]);
}
impl<A, B, C, D, E> Bundle for (A, B, C, D, E)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
]);
}
impl<A, B, C, D, E, F> Bundle for (A, B, C, D, E, F)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
]);
}
impl<A, B, C, D, E, F, G> Bundle for (A, B, C, D, E, F, G)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
]);
}
impl<A, B, C, D, E, F, G, H> Bundle for (A, B, C, D, E, F, G, H)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
]);
}
impl<A, B, C, D, E, F, G, H, I> Bundle for (A, B, C, D, E, F, G, H, I)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J> Bundle for (A, B, C, D, E, F, G, H, I, J)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K> Bundle for (A, B, C, D, E, F, G, H, I, J, K)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K, L> Bundle for (A, B, C, D, E, F, G, H, I, J, K, L)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
L: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
TypeInfo::of::<L>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K, L, M> Bundle for (A, B, C, D, E, F, G, H, I, J, K, L, M)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
L: Component,
M: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
TypeInfo::of::<L>(),
TypeInfo::of::<M>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N> Bundle for (A, B, C, D, E, F, G, H, I, J, K, L, M, N)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
L: Component,
M: Component,
N: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
TypeInfo::of::<L>(),
TypeInfo::of::<M>(),
TypeInfo::of::<N>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> Bundle
for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
L: Component,
M: Component,
N: Component,
O: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
TypeInfo::of::<L>(),
TypeInfo::of::<M>(),
TypeInfo::of::<N>(),
TypeInfo::of::<O>(),
]);
}
impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P> Bundle
for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)
where
A: Component,
B: Component,
C: Component,
D: Component,
E: Component,
F: Component,
G: Component,
H: Component,
I: Component,
J: Component,
K: Component,
L: Component,
M: Component,
N: Component,
O: Component,
P: Component,
{
const COMPONENT_INFO: &'static [TypeInfo] = &sorted_types([
TypeInfo::of::<A>(),
TypeInfo::of::<B>(),
TypeInfo::of::<C>(),
TypeInfo::of::<D>(),
TypeInfo::of::<E>(),
TypeInfo::of::<F>(),
TypeInfo::of::<G>(),
TypeInfo::of::<H>(),
TypeInfo::of::<I>(),
TypeInfo::of::<J>(),
TypeInfo::of::<K>(),
TypeInfo::of::<L>(),
TypeInfo::of::<M>(),
TypeInfo::of::<N>(),
TypeInfo::of::<O>(),
TypeInfo::of::<P>(),
]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment