]> git.proxmox.com Git - rustc.git/blob - src/libcore/array.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libcore / array.rs
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.
14 //!
15 //! *[See also the array primitive type](../../std/primitive.array.html).*
16
17 #![unstable(feature = "fixed_size_array",
18 reason = "traits and impls are better expressed through generic \
19 integer constants",
20 issue = "27778")]
21
22 use borrow::{Borrow, BorrowMut};
23 use clone::Clone;
24 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
25 use convert::{AsRef, AsMut};
26 use default::Default;
27 use fmt;
28 use hash::{Hash, self};
29 use iter::IntoIterator;
30 use marker::{Copy, Sized, Unsize};
31 use option::Option;
32 use slice::{Iter, IterMut, SliceExt};
33
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.
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> {
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
54 unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
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
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
97 // macro for implementing n-ary tuple functions and operations
98 macro_rules! array_impls {
99 ($($N:expr)+) => {
100 $(
101 impl<T> AsRef<[T]> for [T; $N] {
102 #[inline]
103 fn as_ref(&self) -> &[T] {
104 &self[..]
105 }
106 }
107
108 impl<T> AsMut<[T]> for [T; $N] {
109 #[inline]
110 fn as_mut(&mut self) -> &mut [T] {
111 &mut self[..]
112 }
113 }
114
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
129 #[stable(feature = "rust1", since = "1.0.0")]
130 impl<T:Copy> Clone for [T; $N] {
131 fn clone(&self) -> [T; $N] {
132 *self
133 }
134 }
135
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] {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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()
167 }
168 }
169
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] }
177
178 #[stable(feature = "rust1", since = "1.0.0")]
179 impl<T:Eq> Eq for [T; $N] { }
180
181 #[stable(feature = "rust1", since = "1.0.0")]
182 impl<T:PartialOrd> PartialOrd for [T; $N] {
183 #[inline]
184 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
185 PartialOrd::partial_cmp(&&self[..], &&other[..])
186 }
187 #[inline]
188 fn lt(&self, other: &[T; $N]) -> bool {
189 PartialOrd::lt(&&self[..], &&other[..])
190 }
191 #[inline]
192 fn le(&self, other: &[T; $N]) -> bool {
193 PartialOrd::le(&&self[..], &&other[..])
194 }
195 #[inline]
196 fn ge(&self, other: &[T; $N]) -> bool {
197 PartialOrd::ge(&&self[..], &&other[..])
198 }
199 #[inline]
200 fn gt(&self, other: &[T; $N]) -> bool {
201 PartialOrd::gt(&&self[..], &&other[..])
202 }
203 }
204
205 #[stable(feature = "rust1", since = "1.0.0")]
206 impl<T:Ord> Ord for [T; $N] {
207 #[inline]
208 fn cmp(&self, other: &[T; $N]) -> Ordering {
209 Ord::cmp(&&self[..], &&other[..])
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 }
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}