]> git.lizzy.rs Git - rust.git/blob - src/libcore/array.rs
Rollup merge of #27499 - barosl:macro-doc-raw-str-hashes, r=nikomatsakis
[rust.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](../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}