1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#![doc(html_root_url = "http://docs.rs/const-default/1.0.0")]
#![cfg_attr(feature = "unstable-docs", feature(doc_cfg))]
#[cfg(feature = "derive")]
#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "derive")))]
pub use dyn_any_derive::DynAny;
use std::any::TypeId;
pub trait DynAny<'a> {
fn type_id(&self) -> TypeId;
}
impl<'a> DynAny<'a> for f32 {
fn type_id(&self) -> TypeId {
TypeId::of::<f32>()
}
}
impl<'a, T: 'static> DynAny<'a> for &T {
fn type_id(&self) -> TypeId {
TypeId::of::<&'static T>()
}
}
pub fn downcast_ref<'a, V: StaticType<'a>>(
i: &'a dyn DynAny<'a>,
) -> Option<&'a V> {
if i.type_id() == std::any::TypeId::of::<<V as StaticType>::Static>() {
let ptr = i as *const dyn DynAny<'a> as *const V;
Some(unsafe { &*ptr })
} else {
None
}
}
pub trait StaticType<'a>: 'a {
type Static: 'static + ?Sized;
fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<Self::Static>()
}
}
pub trait StaticTypeSized<'a>: 'a {
type Static: 'static;
fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<Self::Static>()
}
}
impl<'a, T: StaticTypeSized<'a>> StaticType<'a> for T {
type Static = <T as StaticTypeSized<'a>>::Static;
}
pub trait StaticTypeClone<'a>: 'a {
type Static: 'static + Clone;
fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<Self::Static>()
}
}
impl<'a, T: StaticTypeClone<'a>> StaticTypeSized<'a> for T {
type Static = <T as StaticTypeClone<'a>>::Static;
}
macro_rules! impl_type {
($($id:ident$(<$($(($l:lifetime, $s:lifetime)),*|)?$($T:ident),*>)?),*) => {
$(
impl<'a, $($($T: 'a + $crate::StaticTypeSized<'a> + Sized,)*)?> $crate::StaticTypeSized<'a> for $id $(<$($($l,)*)?$($T, )*>)?{
type Static = $id$(<$($($s,)*)?$(<$T as $crate::StaticTypeSized<'a>>::Static,)*>)?;
}
)*
};
}
impl<'a, T: Clone + StaticTypeClone<'a>> StaticTypeClone<'a>
for std::borrow::Cow<'a, T>
{
type Static = std::borrow::Cow<'static, <T as StaticTypeSized<'a>>::Static>;
}
impl<'a, T: StaticTypeSized<'a>> StaticTypeSized<'a> for *const [T] {
type Static = *const [<T as StaticTypeSized<'a>>::Static];
}
impl<'a, T: StaticTypeSized<'a>> StaticTypeSized<'a> for *mut [T] {
type Static = *mut [<T as StaticTypeSized<'a>>::Static];
}
impl<'a, T: StaticTypeSized<'a>> StaticTypeSized<'a> for &'a [T] {
type Static = &'static [<T as StaticTypeSized<'a>>::Static];
}
impl<'a> StaticTypeSized<'a> for &'a str {
type Static = &'static str;
}
impl<'a> StaticTypeSized<'a> for () {
type Static = ();
}
impl<'a, T: 'a + StaticTypeClone<'a>> StaticTypeClone<'a> for &'a T {
type Static = &'static <T as StaticTypeClone<'a>>::Static;
}
impl<'a, T: StaticTypeSized<'a>, const N: usize> StaticTypeSized<'a>
for [T; N]
{
type Static = [<T as StaticTypeSized<'a>>::Static; N];
}
use core::{
cell::{Cell, RefCell, UnsafeCell},
iter::Empty,
marker::{PhantomData, PhantomPinned},
mem::{ManuallyDrop, MaybeUninit},
num::Wrapping,
time::Duration,
};
use std::{
collections::*,
sync::{atomic::*, *},
vec::Vec,
};
impl_type!(Option<T>,Result<T, E>,Cell<T>,UnsafeCell<T>,RefCell<T>,MaybeUninit<T>,
Vec<T>, String, BTreeMap<K,V>,BTreeSet<V>, LinkedList<T>, VecDeque<T>,
BinaryHeap<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
Wrapping<T>, Duration, Once, Mutex<T>, RwLock<T>, bool, f32, f64, char,
u8, AtomicU8, u16,AtomicU16, u32,AtomicU32, u64,AtomicU64, usize,AtomicUsize,
i8,AtomicI8, i16,AtomicI16, i32,AtomicI32, i64,AtomicI64, isize,AtomicIsize,
i128, u128, AtomicBool, AtomicPtr<T>
);
macro_rules! impl_tuple {
(@rec $t:ident) => { };
(@rec $_:ident $($t:ident)+) => {
impl_tuple! { @impl $($t)* }
impl_tuple! { @rec $($t)* }
};
(@impl $($t:ident)*) => {
impl<'dyn_any, $($t: StaticTypeSized<'dyn_any>,)*> StaticTypeSized<'dyn_any> for ($($t,)*) {
type Static = ($(<$t as $crate::StaticTypeSized<'dyn_any>>::Static,)*);
}
};
($($t:ident)*) => {
impl_tuple! { @rec _t $($t)* }
};
}
impl_tuple! {
A B C D E F G H I J K L
}