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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
use ;
use crateCast;
///
/// Defines methods to convert a reference to a slice of a type to a
/// transmuted reference to a slice of the specified type without
/// copying data.
///
/// # Example
///
/// In the example below, references to three types of arrays are
/// converted among them. It is possible because their binary form on
/// the memory are the same.
///
/// ```
/// # fn main() { test(); }
/// # fn test() -> Option<()> {
/// use castflip::experimental::Reslice;
/// use castflip::Cast;
///
/// #[repr(C)]
/// #[derive(Cast, PartialEq, Debug)]
/// struct Duo {
/// a: u16,
/// b: u16
/// }
///
/// #[repr(C)]
/// #[derive(Cast, PartialEq, Debug)]
/// struct Trio {
/// x: u16,
/// y: u16,
/// z: u16
/// }
///
/// // Input data. They have different types but the same binary form.
/// let solo1: [u16; 6] = [ 100, 200, 300, 400, 500, 600 ];
/// let duo1 = [ Duo { a: 100, b: 200 },
/// Duo { a: 300, b: 400 },
/// Duo { a: 500, b: 600 } ];
/// let trio1 = [ Trio { x: 100, y: 200, z: 300 },
/// Trio { x: 400, y: 500, z: 600 } ];
///
/// unsafe {
/// // Convert the original reference to `duo1` into a transmuted
/// // reference to &[u16] without copying data.
/// let duo_to_solo = duo1.reslice::<u16>()?;
/// assert_eq!(duo_to_solo, &solo1[..]);
///
/// // Convert the original reference to `solo1` into a transmuted
/// // reference to &Duo without copying data.
/// let solo_to_duo = solo1.reslice::<Duo>()?;
/// assert_eq!(solo_to_duo, &duo1[..]);
/// }
///
/// unsafe {
/// // Convert the original reference to `trio1` into a transmuted
/// // reference to &[u16] without copying data.
/// let trio_to_solo = trio1.reslice::<u16>()?;
/// assert_eq!(trio_to_solo, &solo1[..]);
///
/// // Convert the original reference to `solo1` into a transmuted
/// // reference to &Trio without copying data.
/// let solo_to_trio = solo1.reslice::<Trio>()?;
/// assert_eq!(solo_to_trio, &trio1[..]);
/// }
///
/// unsafe {
/// // Convert the original reference to `duo1` into a transmuted
/// // reference to &Trio without copying data.
/// let duo_to_trio = duo1.reslice::<Trio>()?;
/// assert_eq!(duo_to_trio, &trio1[..]);
///
/// // Convert the original reference to `trio1` into a transmuted
/// // reference to &Duo without copying data.
/// let trio_to_duo = trio1.reslice::<Duo>()?;
/// assert_eq!(trio_to_duo, &duo1[..]);
/// }
/// # Some(())
/// # }
/// ```
///
/// # Description
///
/// All methods in trait `Reslice` convert a reference to a slice into
/// a transmuted reference to a slice of the specified type without
/// copying data.
///
/// The size of the original slice and the size of the transmuted
/// slice must be the same. And the address of the original slice
/// must satisfy the requirement of the alignment of the transmuted
/// slice. If these requirements are satisfied, resulting reference
/// is returned in `Some`(). Otherwise, None is returned.
///
/// # Safety
///
/// We do not understand clearly what kind of problems could occur
/// with this trait.
///
/// Because the Rust compiler would not recognize what is happening,
/// it may reorder instructions unexpectedly. When a transmuted
/// reference is created by this trait, it would be better not to use
/// the original reference until the transmuted reference is dropped,
/// expecially when the original reference is mutable.
///
/// When creating a transmuted reference with this trait, take care
/// with the alignment issues.
///