]> git.lizzy.rs Git - rust.git/blob - src/libcore/array.rs
Auto merge of #29513 - apasel422:issue-23217, r=alexcrichton
[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 for implementing n-ary tuple functions and operations
66 macro_rules! array_impls {
67     ($($N:expr)+) => {
68         $(
69             impl<T> AsRef<[T]> for [T; $N] {
70                 #[inline]
71                 fn as_ref(&self) -> &[T] {
72                     &self[..]
73                 }
74             }
75
76             impl<T> AsMut<[T]> for [T; $N] {
77                 #[inline]
78                 fn as_mut(&mut self) -> &mut [T] {
79                     &mut self[..]
80                 }
81             }
82
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
97             #[stable(feature = "rust1", since = "1.0.0")]
98             impl<T:Copy> Clone for [T; $N] {
99                 fn clone(&self) -> [T; $N] {
100                     *self
101                 }
102             }
103
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] {
113                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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()
135                 }
136             }
137
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] }
145
146             #[stable(feature = "rust1", since = "1.0.0")]
147             impl<T:Eq> Eq for [T; $N] { }
148
149             #[stable(feature = "rust1", since = "1.0.0")]
150             impl<T:PartialOrd> PartialOrd for [T; $N] {
151                 #[inline]
152                 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
153                     PartialOrd::partial_cmp(&&self[..], &&other[..])
154                 }
155                 #[inline]
156                 fn lt(&self, other: &[T; $N]) -> bool {
157                     PartialOrd::lt(&&self[..], &&other[..])
158                 }
159                 #[inline]
160                 fn le(&self, other: &[T; $N]) -> bool {
161                     PartialOrd::le(&&self[..], &&other[..])
162                 }
163                 #[inline]
164                 fn ge(&self, other: &[T; $N]) -> bool {
165                     PartialOrd::ge(&&self[..], &&other[..])
166                 }
167                 #[inline]
168                 fn gt(&self, other: &[T; $N]) -> bool {
169                     PartialOrd::gt(&&self[..], &&other[..])
170                 }
171             }
172
173             #[stable(feature = "rust1", since = "1.0.0")]
174             impl<T:Ord> Ord for [T; $N] {
175                 #[inline]
176                 fn cmp(&self, other: &[T; $N]) -> Ordering {
177                     Ord::cmp(&&self[..], &&other[..])
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 }
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}