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