1use std::cmp;
10use std::fmt;
11use std::hash::{Hash, Hasher};
12use std::mem;
13use std::ops;
14
15use traits::*;
16
17#[repr(packed)]
43pub struct Unaligned<T : LmdbRawIfUnaligned>(T);
44
45impl<T : LmdbRawIfUnaligned> Clone for Unaligned<T> {
46 fn clone(&self) -> Self {
47 Unaligned(self.0)
48 }
49}
50
51impl<T : LmdbRawIfUnaligned> Copy for Unaligned<T> { }
52
53unsafe impl<T : LmdbRawIfUnaligned> LmdbRaw for Unaligned<T> {
54 fn reported_type() -> String {
55 format!("Unaligned<{}>", T::reported_type())
56 }
57}
58
59unsafe impl<T : LmdbRawIfUnaligned + LmdbOrdKeyIfUnaligned> LmdbOrdKey
60for Unaligned<T> {
61 fn ordered_by_bytes() -> bool { T::ordered_by_bytes() }
62 fn ordered_as_integer() -> bool { T::ordered_as_integer() }
63}
64
65impl<T : LmdbRawIfUnaligned> Unaligned<T> {
66 pub fn new(t: T) -> Self {
68 Unaligned(t)
69 }
70
71 pub fn of_ref(t: &T) -> &Self {
75 unsafe { mem::transmute(t) }
76 }
77
78 pub fn of_mut(t: &mut T) -> &mut Self {
82 unsafe { mem::transmute(t) }
83 }
84
85 pub fn get(&self) -> T { self.0 }
90
91 pub fn set(&mut self, t: T) { self.0 = t; }
93}
94
95pub fn unaligned<T : LmdbRawIfUnaligned>(t: &T) -> &Unaligned<T> {
97 Unaligned::of_ref(t)
98}
99
100macro_rules! deleg_fmt {
105 ($tr:ident) => {
106 impl<T : LmdbRawIfUnaligned> fmt::$tr for Unaligned<T> where T : fmt::$tr {
107 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
108 let inner = self.0;
109 inner.fmt(fmt)
110 }
111 }
112 }
113}
114
115deleg_fmt!(Binary);
116deleg_fmt!(Debug);
117deleg_fmt!(Display);
118deleg_fmt!(LowerExp);
119deleg_fmt!(LowerHex);
120deleg_fmt!(Octal);
121deleg_fmt!(Pointer);
122deleg_fmt!(UpperExp);
123deleg_fmt!(UpperHex);
124
125impl<T : LmdbRawIfUnaligned + cmp::PartialEq<T>>
126cmp::PartialEq<Unaligned<T>> for Unaligned<T> {
127 fn eq(&self, other: &Self) -> bool {
128 let (lhs, rhs) = (self.0, other.0);
129 lhs.eq(&rhs)
130 }
131}
132impl<T : LmdbRawIfUnaligned + cmp::Eq> cmp::Eq for Unaligned<T> { }
133impl<T : LmdbRawIfUnaligned + cmp::PartialOrd<T>>
134cmp::PartialOrd<Unaligned<T>> for Unaligned<T> {
135 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
136 let (lhs, rhs) = (self.0, other.0);
137 lhs.partial_cmp(&rhs)
138 }
139 fn lt(&self, other: &Self) -> bool {
140 let (lhs, rhs) = (self.0, other.0);
141 lhs.lt(&rhs)
142 }
143 fn le(&self, other: &Self) -> bool {
144 let (lhs, rhs) = (self.0, other.0);
145 lhs.le(&rhs)
146 }
147 fn gt(&self, other: &Self) -> bool {
148 let (lhs, rhs) = (self.0, other.0);
149 lhs.gt(&rhs)
150 }
151 fn ge(&self, other: &Self) -> bool {
152 let (lhs, rhs) = (self.0, other.0);
153 lhs.ge(&rhs)
154 }
155}
156impl<T : LmdbRawIfUnaligned + cmp::Ord> cmp::Ord for Unaligned<T> {
157 fn cmp(&self, other: &Self) -> cmp::Ordering {
158 let (lhs, rhs) = (self.0, other.0);
159 lhs.cmp(&rhs)
160 }
161}
162
163impl<T : LmdbRawIfUnaligned + Hash> Hash for Unaligned<T> {
164 fn hash<H : Hasher>(&self, state: &mut H) {
165 let v = self.0;
166 v.hash(state)
167 }
168}
169
170macro_rules! binop {
171 ($tr:ident, $meth:ident) => {
172 impl<T : LmdbRawIfUnaligned + ops::$tr<T>>
173 ops::$tr<Unaligned<T>> for Unaligned<T>
174 where T::Output : LmdbRawIfUnaligned {
175 type Output = Unaligned<T::Output>;
176 fn $meth(self, rhs: Self) -> Self::Output {
177 let (lhs, rhs) = (self.0, rhs.0);
178 Unaligned(lhs.$meth(rhs))
179 }
180 }
181 }
182}
183
184macro_rules! binopeq {
185 ($tr:ident, $meth:ident) => {
186 impl<T : LmdbRawIfUnaligned + ops::$tr<T>>
187 ops::$tr<Unaligned<T>> for Unaligned<T> {
188 fn $meth(&mut self, rhs: Self) {
189 let (mut lhs, rhs) = (self.0, rhs.0);
190 lhs.$meth(rhs);
191 self.0 = lhs;
192 }
193 }
194 }
195}
196
197binop!(Add, add);
198binop!(BitAnd, bitand);
199binop!(BitOr, bitor);
200binop!(BitXor, bitxor);
201binop!(Div, div);
202binop!(Mul, mul);
203binop!(Rem, rem);
204binop!(Shl, shl);
205binop!(Shr, shr);
206binop!(Sub, sub);
207
208binopeq!(AddAssign, add_assign);
209binopeq!(BitAndAssign, bitand_assign);
210binopeq!(BitOrAssign, bitor_assign);
211binopeq!(BitXorAssign, bitxor_assign);
212binopeq!(DivAssign, div_assign);
213binopeq!(MulAssign, mul_assign);
214binopeq!(RemAssign, rem_assign);
215binopeq!(ShlAssign, shl_assign);
216binopeq!(ShrAssign, shr_assign);
217binopeq!(SubAssign, sub_assign);