1extern crate proc_macro;
2#[macro_use]
3extern crate syn;
4#[macro_use]
5extern crate quote;
6
7use proc_macro::TokenStream;
8use syn::DeriveInput;
9
10#[proc_macro_derive(PtrEq)]
11pub fn derive_ptr_eq(input: TokenStream) -> TokenStream {
12 let input = parse_macro_input!(input as DeriveInput);
13 let name = input.ident;
14 let (impl_gn, ty_gn, where_cl) = input.generics.split_for_impl();
15
16 let expanded = quote! {
17 unsafe impl #impl_gn PtrEq for #name #ty_gn #where_cl {}
18
19 impl #impl_gn ::core::hash::Hash for &#name #ty_gn #where_cl {
22 fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
23 ((*self) as *const (#name #ty_gn)).hash(state)
24 }
25 }
26
27 impl #impl_gn ::core::hash::Hash for &mut #name #ty_gn #where_cl {
30 fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
31 ((*self) as *const (#name #ty_gn)).hash(state)
32 }
33 }
34
35 impl #impl_gn ::core::cmp::PartialEq<&#name #ty_gn> for &#name #ty_gn #where_cl {
38 #[inline]
39 fn eq(&self, other: &&#name #ty_gn) -> bool {
40 ::core::ptr::eq(*self, *other)
41 }
42 }
43
44 impl #impl_gn ::core::cmp::Eq for &#name #ty_gn #where_cl {}
45
46 impl #impl_gn ::core::cmp::PartialOrd<&#name #ty_gn> for &#name #ty_gn #where_cl {
47 #[inline]
48 fn partial_cmp(&self, other: &&#name #ty_gn) -> ::core::option::Option<::core::cmp::Ordering> {
49 ((*self) as *const (#name #ty_gn)).partial_cmp(&((*other) as *const (#name #ty_gn)))
50 }
51 }
52
53 impl #impl_gn ::core::cmp::Ord for &#name #ty_gn #where_cl {
54 #[inline]
55 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
56 ((*self) as *const (#name #ty_gn)).cmp(&((*other) as *const (#name #ty_gn)))
57 }
58 }
59
60 impl #impl_gn ::core::cmp::PartialEq<&mut #name #ty_gn> for &mut #name #ty_gn #where_cl {
63 #[inline]
64 fn eq(&self, other: &&mut #name #ty_gn) -> bool {
65 ::core::ptr::eq(*self, *other)
66 }
67 }
68
69 impl #impl_gn ::core::cmp::Eq for &mut #name #ty_gn #where_cl {}
70
71 impl #impl_gn ::core::cmp::PartialOrd<&mut #name #ty_gn> for &mut #name #ty_gn #where_cl {
72 #[inline]
73 fn partial_cmp(&self, other: &&mut #name #ty_gn) -> ::core::option::Option<::core::cmp::Ordering> {
74 ((*self) as *const (#name #ty_gn)).partial_cmp(&((*other) as *const (#name #ty_gn)))
75 }
76 }
77
78 impl #impl_gn ::core::cmp::Ord for &mut #name #ty_gn #where_cl {
79 #[inline]
80 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
81 ((*self) as *const (#name #ty_gn)).cmp(&((*other) as *const (#name #ty_gn)))
82 }
83 }
84
85 impl #impl_gn ::core::cmp::PartialEq<&mut #name #ty_gn> for &#name #ty_gn #where_cl {
88 #[inline]
89 fn eq(&self, other: &&mut #name #ty_gn) -> bool {
90 ::core::ptr::eq(*self, *other)
91 }
92 }
93
94 impl #impl_gn ::core::cmp::PartialOrd<&mut #name #ty_gn> for &#name #ty_gn #where_cl {
95 #[inline]
96 fn partial_cmp(&self, other: &&mut #name #ty_gn) -> ::core::option::Option<::core::cmp::Ordering> {
97 ((*self) as *const (#name #ty_gn)).partial_cmp(&((*other) as *const (#name #ty_gn)))
98 }
99 }
100
101 impl #impl_gn ::core::cmp::PartialEq<&#name #ty_gn> for &mut #name #ty_gn #where_cl {
104 #[inline]
105 fn eq(&self, other: &&#name #ty_gn) -> bool {
106 ::core::ptr::eq(*self, *other)
107 }
108 }
109
110 impl #impl_gn ::core::cmp::PartialOrd<&#name #ty_gn> for &mut #name #ty_gn #where_cl {
111 #[inline]
112 fn partial_cmp(&self, other: &&#name #ty_gn) -> ::core::option::Option<::core::cmp::Ordering> {
113 ((*self) as *const (#name #ty_gn)).partial_cmp(&((*other) as *const (#name #ty_gn)))
114 }
115 }
116 };
117
118 expanded.into()
119}