Skip to main content

ptr_eq_macros/
lib.rs

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        // &T
20
21        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        // &mut T
28
29        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        // &T and &T
36
37        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        // &mut T and &mut T
61
62        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        // &T and &mut T
86
87        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        // &mut T and &T
102
103        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}