1
use std::collections::VecDeque;
2
use std::mem::transmute;
3

            
4
use merc_collections::IndexedSet;
5

            
6
use crate::SymbolRef;
7
use crate::aterm::ATermRef;
8

            
9
pub trait Transmutable {
10
    type Target<'a>
11
    where
12
        Self: 'a;
13

            
14
    /// Transmute the lifetime of the object to 'a, which is shorter than the given lifetime.
15
    fn transmute_lifetime<'a>(&'_ self) -> &'a Self::Target<'a>;
16

            
17
    /// Transmute the lifetime of the object to 'a, which is shorter than the given lifetime.
18
    fn transmute_lifetime_mut<'a>(&'_ mut self) -> &'a mut Self::Target<'a>;
19
}
20

            
21
impl Transmutable for ATermRef<'static> {
22
    type Target<'a> = ATermRef<'a>;
23

            
24
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
25
        unsafe { transmute::<&Self, &'a ATermRef<'a>>(self) }
26
    }
27

            
28
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
29
        unsafe { transmute::<&mut Self, &'a mut ATermRef<'a>>(self) }
30
    }
31
}
32

            
33
impl Transmutable for SymbolRef<'static> {
34
    type Target<'a> = SymbolRef<'a>;
35

            
36
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
37
        unsafe { transmute::<&Self, &'a SymbolRef<'a>>(self) }
38
    }
39

            
40
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
41
        unsafe { transmute::<&mut Self, &'a mut SymbolRef<'a>>(self) }
42
    }
43
}
44

            
45
impl<T: Transmutable> Transmutable for Option<T> {
46
    type Target<'a>
47
        = Option<T>
48
    where
49
        T: 'a;
50

            
51
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
52
        unsafe { transmute::<&Self, &'a Option<T>>(self) }
53
    }
54

            
55
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
56
        unsafe { transmute::<&mut Self, &'a mut Option<T>>(self) }
57
    }
58
}
59

            
60
impl<T: Transmutable> Transmutable for Vec<T> {
61
    type Target<'a>
62
        = Vec<T::Target<'a>>
63
    where
64
        T: 'a;
65

            
66
262523351
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
67
262523351
        unsafe { transmute::<&Self, &'a Vec<T::Target<'a>>>(self) }
68
262523351
    }
69

            
70
60539036
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
71
60539036
        unsafe { transmute::<&mut Self, &'a mut Vec<T::Target<'a>>>(self) }
72
60539036
    }
73
}
74

            
75
impl<T: Transmutable> Transmutable for VecDeque<T> {
76
    type Target<'a>
77
        = VecDeque<T::Target<'a>>
78
    where
79
        T: 'a;
80

            
81
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
82
        unsafe { transmute::<&Self, &'a VecDeque<T::Target<'a>>>(self) }
83
    }
84

            
85
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
86
        unsafe { transmute::<&mut Self, &'a mut VecDeque<T::Target<'a>>>(self) }
87
    }
88
}
89

            
90
impl<T: Transmutable> Transmutable for IndexedSet<T> {
91
    type Target<'a>
92
        = IndexedSet<T::Target<'a>>
93
    where
94
        T: 'a;
95

            
96
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
97
        unsafe { transmute::<&Self, &'a IndexedSet<T::Target<'a>>>(self) }
98
    }
99

            
100
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
101
        unsafe { transmute::<&mut Self, &'a mut IndexedSet<T::Target<'a>>>(self) }
102
    }
103
}
104

            
105
// In Rust Its not yet possible to implement it for any tuples, so we implement it for some common sizes.
106
impl<T1: Transmutable, T2: Transmutable> Transmutable for (T1, T2) {
107
    type Target<'a>
108
        = (T1::Target<'a>, T2::Target<'a>)
109
    where
110
        T1: 'a,
111
        T2: 'a;
112

            
113
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
114
        unsafe { transmute::<&Self, &'a (T1::Target<'a>, T2::Target<'a>)>(self) }
115
    }
116

            
117
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
118
        unsafe { transmute::<&mut Self, &'a mut (T1::Target<'a>, T2::Target<'a>)>(self) }
119
    }
120
}
121

            
122
impl Transmutable for bool {
123
    type Target<'a> = bool;
124

            
125
    fn transmute_lifetime<'a>(&self) -> &'a Self::Target<'a> {
126
        unsafe { transmute::<&Self, &'a bool>(self) }
127
    }
128

            
129
    fn transmute_lifetime_mut<'a>(&mut self) -> &'a mut Self::Target<'a> {
130
        unsafe { transmute::<&mut Self, &'a mut bool>(self) }
131
    }
132
}