]>
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 | ||
1a4d82fc JJ |
65 | // macro for implementing n-ary tuple functions and operations |
66 | macro_rules! array_impls { | |
67 | ($($N:expr)+) => { | |
68 | $( | |
c34b1796 AL |
69 | impl<T> AsRef<[T]> for [T; $N] { |
70 | #[inline] | |
71 | fn as_ref(&self) -> &[T] { | |
72 | &self[..] | |
73 | } | |
74 | } | |
75 | ||
c34b1796 AL |
76 | impl<T> AsMut<[T]> for [T; $N] { |
77 | #[inline] | |
78 | fn as_mut(&mut self) -> &mut [T] { | |
79 | &mut self[..] | |
80 | } | |
81 | } | |
82 | ||
e9174d1e SL |
83 | #[stable(feature = "array_borrow", since = "1.4.0")] |
84 | impl<T> Borrow<[T]> for [T; $N] { | |
85 | fn borrow(&self) -> &[T] { | |
86 | self | |
87 | } | |
88 | } | |
89 | ||
90 | #[stable(feature = "array_borrow", since = "1.4.0")] | |
91 | impl<T> BorrowMut<[T]> for [T; $N] { | |
92 | fn borrow_mut(&mut self) -> &mut [T] { | |
93 | self | |
94 | } | |
95 | } | |
96 | ||
85aaf69f | 97 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
98 | impl<T:Copy> Clone for [T; $N] { |
99 | fn clone(&self) -> [T; $N] { | |
100 | *self | |
101 | } | |
102 | } | |
103 | ||
85aaf69f SL |
104 | #[stable(feature = "rust1", since = "1.0.0")] |
105 | impl<T: Hash> Hash for [T; $N] { | |
106 | fn hash<H: hash::Hasher>(&self, state: &mut H) { | |
107 | Hash::hash(&self[..], state) | |
108 | } | |
109 | } | |
110 | ||
111 | #[stable(feature = "rust1", since = "1.0.0")] | |
112 | impl<T: fmt::Debug> fmt::Debug for [T; $N] { | |
1a4d82fc | 113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f SL |
114 | fmt::Debug::fmt(&&self[..], f) |
115 | } | |
116 | } | |
117 | ||
118 | #[stable(feature = "rust1", since = "1.0.0")] | |
119 | impl<'a, T> IntoIterator for &'a [T; $N] { | |
120 | type Item = &'a T; | |
121 | type IntoIter = Iter<'a, T>; | |
122 | ||
123 | fn into_iter(self) -> Iter<'a, T> { | |
124 | self.iter() | |
125 | } | |
126 | } | |
127 | ||
128 | #[stable(feature = "rust1", since = "1.0.0")] | |
129 | impl<'a, T> IntoIterator for &'a mut [T; $N] { | |
130 | type Item = &'a mut T; | |
131 | type IntoIter = IterMut<'a, T>; | |
132 | ||
133 | fn into_iter(self) -> IterMut<'a, T> { | |
134 | self.iter_mut() | |
1a4d82fc JJ |
135 | } |
136 | } | |
137 | ||
c34b1796 AL |
138 | // NOTE: some less important impls are omitted to reduce code bloat |
139 | __impl_slice_eq1! { [A; $N], [B; $N] } | |
140 | __impl_slice_eq2! { [A; $N], [B] } | |
141 | __impl_slice_eq2! { [A; $N], &'b [B] } | |
142 | __impl_slice_eq2! { [A; $N], &'b mut [B] } | |
143 | // __impl_slice_eq2! { [A; $N], &'b [B; $N] } | |
144 | // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } | |
1a4d82fc | 145 | |
85aaf69f | 146 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
147 | impl<T:Eq> Eq for [T; $N] { } |
148 | ||
85aaf69f | 149 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
150 | impl<T:PartialOrd> PartialOrd for [T; $N] { |
151 | #[inline] | |
152 | fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { | |
85aaf69f | 153 | PartialOrd::partial_cmp(&&self[..], &&other[..]) |
1a4d82fc JJ |
154 | } |
155 | #[inline] | |
156 | fn lt(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 157 | PartialOrd::lt(&&self[..], &&other[..]) |
1a4d82fc JJ |
158 | } |
159 | #[inline] | |
160 | fn le(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 161 | PartialOrd::le(&&self[..], &&other[..]) |
1a4d82fc JJ |
162 | } |
163 | #[inline] | |
164 | fn ge(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 165 | PartialOrd::ge(&&self[..], &&other[..]) |
1a4d82fc JJ |
166 | } |
167 | #[inline] | |
168 | fn gt(&self, other: &[T; $N]) -> bool { | |
85aaf69f | 169 | PartialOrd::gt(&&self[..], &&other[..]) |
1a4d82fc JJ |
170 | } |
171 | } | |
172 | ||
85aaf69f | 173 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
174 | impl<T:Ord> Ord for [T; $N] { |
175 | #[inline] | |
176 | fn cmp(&self, other: &[T; $N]) -> Ordering { | |
85aaf69f | 177 | Ord::cmp(&&self[..], &&other[..]) |
1a4d82fc JJ |
178 | } |
179 | } | |
180 | )+ | |
181 | } | |
182 | } | |
183 | ||
184 | array_impls! { | |
185 | 0 1 2 3 4 5 6 7 8 9 | |
186 | 10 11 12 13 14 15 16 17 18 19 | |
187 | 20 21 22 23 24 25 26 27 28 29 | |
188 | 30 31 32 | |
189 | } | |
e9174d1e SL |
190 | |
191 | // The Default impls cannot be generated using the array_impls! macro because | |
192 | // they require array literals. | |
193 | ||
194 | macro_rules! array_impl_default { | |
195 | {$n:expr, $t:ident $($ts:ident)*} => { | |
196 | #[stable(since = "1.4.0", feature = "array_default")] | |
197 | impl<T> Default for [T; $n] where T: Default { | |
198 | fn default() -> [T; $n] { | |
199 | [$t::default(), $($ts::default()),*] | |
200 | } | |
201 | } | |
202 | array_impl_default!{($n - 1), $($ts)*} | |
203 | }; | |
204 | {$n:expr,} => { | |
205 | #[stable(since = "1.4.0", feature = "array_default")] | |
206 | impl<T> Default for [T; $n] { | |
207 | fn default() -> [T; $n] { [] } | |
208 | } | |
209 | }; | |
210 | } | |
211 | ||
212 | 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} |