]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Implementations of things like `Eq` for fixed-length arrays | |
12 | //! up to a certain length. Eventually we should able to generalize | |
13 | //! to all lengths. | |
c1a9b12d SL |
14 | //! |
15 | //! *[See also the array primitive type](../primitive.array.html).* | |
1a4d82fc | 16 | |
62682a34 SL |
17 | #![unstable(feature = "fixed_size_array", |
18 | reason = "traits and impls are better expressed through generic \ | |
e9174d1e SL |
19 | integer constants", |
20 | issue = "27778")] | |
c34b1796 | 21 | |
e9174d1e | 22 | use borrow::{Borrow, BorrowMut}; |
1a4d82fc JJ |
23 | use clone::Clone; |
24 | use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; | |
c34b1796 | 25 | use convert::{AsRef, AsMut}; |
e9174d1e | 26 | use default::Default; |
1a4d82fc | 27 | use fmt; |
85aaf69f SL |
28 | use hash::{Hash, self}; |
29 | use iter::IntoIterator; | |
e9174d1e | 30 | use marker::{Copy, Sized, Unsize}; |
1a4d82fc | 31 | use option::Option; |
85aaf69f | 32 | use slice::{Iter, IterMut, SliceExt}; |
1a4d82fc | 33 | |
c34b1796 AL |
34 | /// Utility trait implemented only on arrays of fixed size |
35 | /// | |
36 | /// This trait can be used to implement other traits on fixed-size arrays | |
37 | /// without causing much metadata bloat. | |
b039eaaf SL |
38 | /// |
39 | /// The trait is marked unsafe in order to restrict implementors to fixed-size | |
40 | /// arrays. User of this trait can assume that implementors have the exact | |
41 | /// layout in memory of a fixed size array (for example, for unsafe | |
42 | /// initialization). | |
43 | /// | |
44 | /// Note that the traits AsRef and AsMut provide similar methods for types that | |
45 | /// may not be fixed-size arrays. Implementors should prefer those traits | |
46 | /// instead. | |
47 | pub unsafe trait FixedSizeArray<T> { | |
c34b1796 AL |
48 | /// Converts the array to immutable slice |
49 | fn as_slice(&self) -> &[T]; | |
50 | /// Converts the array to mutable slice | |
51 | fn as_mut_slice(&mut self) -> &mut [T]; | |
52 | } | |
53 | ||
b039eaaf | 54 | unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A { |
e9174d1e SL |
55 | #[inline] |
56 | fn as_slice(&self) -> &[T] { | |
57 | self | |
58 | } | |
59 | #[inline] | |
60 | fn as_mut_slice(&mut self) -> &mut [T] { | |
61 | self | |
62 | } | |
63 | } | |
64 | ||
92a42be0 SL |
65 | macro_rules! __impl_slice_eq1 { |
66 | ($Lhs: ty, $Rhs: ty) => { | |
67 | __impl_slice_eq1! { $Lhs, $Rhs, Sized } | |
68 | }; | |
69 | ($Lhs: ty, $Rhs: ty, $Bound: ident) => { | |
70 | #[stable(feature = "rust1", since = "1.0.0")] | |
71 | impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> { | |
72 | #[inline] | |
73 | fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } | |
74 | #[inline] | |
75 | fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | macro_rules! __impl_slice_eq2 { | |
81 | ($Lhs: ty, $Rhs: ty) => { | |
82 | __impl_slice_eq2! { $Lhs, $Rhs, Sized } | |
83 | }; | |
84 | ($Lhs: ty, $Rhs: ty, $Bound: ident) => { | |
85 | __impl_slice_eq1!($Lhs, $Rhs, $Bound); | |
86 | ||
87 | #[stable(feature = "rust1", since = "1.0.0")] | |
88 | impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> { | |
89 | #[inline] | |
90 | fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] } | |
91 | #[inline] | |
92 | fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] } | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
1a4d82fc JJ |
97 | // macro for implementing n-ary tuple functions and operations |
98 | macro_rules! array_impls { | |
99 | ($($N:expr)+) => { | |
100 | $( | |
c34b1796 AL |
101 | impl<T> AsRef<[T]> for [T; $N] { |
102 | #[inline] | |
103 | fn as_ref(&self) -> &[T] { | |
104 | &self[..] | |
105 | } | |
106 | } | |
107 | ||
c34b1796 AL |
108 | impl<T> AsMut<[T]> for [T; $N] { |
109 | #[inline] | |
110 | fn as_mut(&mut self) -> &mut [T] { | |
111 | &mut self[..] | |
112 | } | |
113 | } | |
114 | ||
e9174d1e SL |
115 | #[stable(feature = "array_borrow", since = "1.4.0")] |
116 | impl<T> Borrow<[T]> for [T; $N] { | |
117 | fn borrow(&self) -> &[T] { | |
118 | self | |
119 | } | |
120 | } | |
121 | ||
122 | #[stable(feature = "array_borrow", since = "1.4.0")] | |
123 | impl<T> BorrowMut<[T]> for [T; $N] { | |
124 | fn borrow_mut(&mut self) -> &mut [T] { | |
125 | self | |
126 | } | |
127 | } | |
128 | ||
85aaf69f | 129 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
130 | impl<T:Copy> Clone for [T; $N] { |
131 | fn clone(&self) -> [T; $N] { | |
132 | *self | |
133 | } | |
134 | } | |
135 | ||
85aaf69f SL |
136 | #[stable(feature = "rust1", since = "1.0.0")] |
137 | impl<T: Hash> Hash for [T; $N] { | |
138 | fn hash<H: hash::Hasher>(&self, state: &mut H) { | |
139 | Hash::hash(&self[..], state) | |
140 | } | |
141 | } | |
142 | ||
143 | #[stable(feature = "rust1", since = "1.0.0")] | |
144 | impl<T: fmt::Debug> fmt::Debug for [T; $N] { | |
1a4d82fc | 145 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f SL |
146 | fmt::Debug::fmt(&&self[..], f) |
147 | } | |
148 | } | |
149 | ||
150 | #[stable(feature = "rust1", since = "1.0.0")] | |
151 | impl<'a, T> IntoIterator for &'a [T; $N] { | |
152 | type Item = &'a T; | |
153 | type IntoIter = Iter<'a, T>; | |
154 | ||
155 | fn into_iter(self) -> Iter<'a, T> { | |
156 | self.iter() | |
157 | } | |
158 | } | |
159 | ||
160 | #[stable(feature = "rust1", since = "1.0.0")] | |
161 | impl<'a, T> IntoIterator for &'a mut [T; $N] { | |
162 | type Item = &'a mut T; | |
163 | type IntoIter = IterMut<'a, T>; | |
164 | ||
165 | fn into_iter(self) -> IterMut<'a, T> { | |
166 | self.iter_mut() | |
1a4d82fc JJ |
167 | } |
168 | } | |
169 | ||
c34b1796 AL |
170 | // NOTE: some less important impls are omitted to reduce code bloat |
171 | __impl_slice_eq1! { [A; $N], [B; $N] } | |
172 | __impl_slice_eq2! { [A; $N], [B] } | |
173 | __impl_slice_eq2! { [A; $N], &'b [B] } | |
174 | __impl_slice_eq2! { [A; $N], &'b mut [B] } | |
175 | // __impl_slice_eq2! { [A; $N], &'b [B; $N] } | |
176 | // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } | |
1a4d82fc | 177 | |
85aaf69f | 178 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
179 | impl<T:Eq> Eq for [T; $N] { } |
180 | ||
85aaf69f | 181 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
182 | impl<T:PartialOrd> PartialOrd for [T; $N] { |
183 | #[inline] | |
184 | fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { | |
85aaf69f | 185 | PartialOrd::partial_cmp(&&self[..], &&other[..]) |
1a4d82fc JJ |
186 | } |
187 | #[inline] | |
188 | fn lt(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 189 | PartialOrd::lt(&&self[..], &&other[..]) |
1a4d82fc JJ |
190 | } |
191 | #[inline] | |
192 | fn le(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 193 | PartialOrd::le(&&self[..], &&other[..]) |
1a4d82fc JJ |
194 | } |
195 | #[inline] | |
196 | fn ge(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 197 | PartialOrd::ge(&&self[..], &&other[..]) |
1a4d82fc JJ |
198 | } |
199 | #[inline] | |
200 | fn gt(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 201 | PartialOrd::gt(&&self[..], &&other[..]) |
1a4d82fc JJ |
202 | } |
203 | } | |
204 | ||
85aaf69f | 205 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
206 | impl<T:Ord> Ord for [T; $N] { |
207 | #[inline] | |
208 | fn cmp(&self, other: &[T; $N]) -> Ordering { | |
85aaf69f | 209 | Ord::cmp(&&self[..], &&other[..]) |
1a4d82fc JJ |
210 | } |
211 | } | |
212 | )+ | |
213 | } | |
214 | } | |
215 | ||
216 | array_impls! { | |
217 | 0 1 2 3 4 5 6 7 8 9 | |
218 | 10 11 12 13 14 15 16 17 18 19 | |
219 | 20 21 22 23 24 25 26 27 28 29 | |
220 | 30 31 32 | |
221 | } | |
e9174d1e SL |
222 | |
223 | // The Default impls cannot be generated using the array_impls! macro because | |
224 | // they require array literals. | |
225 | ||
226 | macro_rules! array_impl_default { | |
227 | {$n:expr, $t:ident $($ts:ident)*} => { | |
228 | #[stable(since = "1.4.0", feature = "array_default")] | |
229 | impl<T> Default for [T; $n] where T: Default { | |
230 | fn default() -> [T; $n] { | |
231 | [$t::default(), $($ts::default()),*] | |
232 | } | |
233 | } | |
234 | array_impl_default!{($n - 1), $($ts)*} | |
235 | }; | |
236 | {$n:expr,} => { | |
237 | #[stable(since = "1.4.0", feature = "array_default")] | |
238 | impl<T> Default for [T; $n] { | |
239 | fn default() -> [T; $n] { [] } | |
240 | } | |
241 | }; | |
242 | } | |
243 | ||
244 | array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} |