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.
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.
11 //! Implementations of things like `Eq` for fixed-length arrays
12 //! up to a certain length. Eventually we should able to generalize
15 //! *[See also the array primitive type](../../std/primitive.array.html).*
17 #![unstable(feature = "fixed_size_array",
18 reason = "traits and impls are better expressed through generic \
22 use borrow::{Borrow, BorrowMut};
26 use hash::{Hash, self};
28 use slice::{Iter, IterMut};
30 /// Utility trait implemented only on arrays of fixed size
32 /// This trait can be used to implement other traits on fixed-size arrays
33 /// without causing much metadata bloat.
35 /// The trait is marked unsafe in order to restrict implementors to fixed-size
36 /// arrays. User of this trait can assume that implementors have the exact
37 /// layout in memory of a fixed size array (for example, for unsafe
40 /// Note that the traits AsRef and AsMut provide similar methods for types that
41 /// may not be fixed-size arrays. Implementors should prefer those traits
43 pub unsafe trait FixedSizeArray<T> {
44 /// Converts the array to immutable slice
45 fn as_slice(&self) -> &[T];
46 /// Converts the array to mutable slice
47 fn as_mut_slice(&mut self) -> &mut [T];
50 unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
52 fn as_slice(&self) -> &[T] {
56 fn as_mut_slice(&mut self) -> &mut [T] {
61 /// The error type returned when a conversion from a slice to an array fails.
62 #[unstable(feature = "try_from", issue = "33417")]
63 #[derive(Debug, Copy, Clone)]
64 pub struct TryFromSliceError(());
66 impl fmt::Display for TryFromSliceError {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 fmt::Display::fmt(self.__description(), f)
73 impl TryFromSliceError {
74 #[unstable(feature = "array_error_internals",
75 reason = "available through Error trait and this method should not \
80 pub fn __description(&self) -> &str {
81 "could not convert slice to array"
85 macro_rules! __impl_slice_eq1 {
86 ($Lhs: ty, $Rhs: ty) => {
87 __impl_slice_eq1! { $Lhs, $Rhs, Sized }
89 ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
90 #[stable(feature = "rust1", since = "1.0.0")]
91 impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
93 fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
95 fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
100 macro_rules! __impl_slice_eq2 {
101 ($Lhs: ty, $Rhs: ty) => {
102 __impl_slice_eq2! { $Lhs, $Rhs, Sized }
104 ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
105 __impl_slice_eq1!($Lhs, $Rhs, $Bound);
107 #[stable(feature = "rust1", since = "1.0.0")]
108 impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
110 fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
112 fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
117 // macro for implementing n-element array functions and operations
118 macro_rules! array_impls {
121 #[stable(feature = "rust1", since = "1.0.0")]
122 impl<T> AsRef<[T]> for [T; $N] {
124 fn as_ref(&self) -> &[T] {
129 #[stable(feature = "rust1", since = "1.0.0")]
130 impl<T> AsMut<[T]> for [T; $N] {
132 fn as_mut(&mut self) -> &mut [T] {
137 #[stable(feature = "array_borrow", since = "1.4.0")]
138 impl<T> Borrow<[T]> for [T; $N] {
139 fn borrow(&self) -> &[T] {
144 #[stable(feature = "array_borrow", since = "1.4.0")]
145 impl<T> BorrowMut<[T]> for [T; $N] {
146 fn borrow_mut(&mut self) -> &mut [T] {
151 #[unstable(feature = "try_from", issue = "33417")]
152 impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
153 type Error = TryFromSliceError;
155 fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
156 if slice.len() == $N {
157 let ptr = slice.as_ptr() as *const [T; $N];
160 Err(TryFromSliceError(()))
165 #[unstable(feature = "try_from", issue = "33417")]
166 impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
167 type Error = TryFromSliceError;
169 fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
170 if slice.len() == $N {
171 let ptr = slice.as_mut_ptr() as *mut [T; $N];
172 unsafe { Ok(&mut *ptr) }
174 Err(TryFromSliceError(()))
179 #[stable(feature = "rust1", since = "1.0.0")]
180 impl<T: Hash> Hash for [T; $N] {
181 fn hash<H: hash::Hasher>(&self, state: &mut H) {
182 Hash::hash(&self[..], state)
186 #[stable(feature = "rust1", since = "1.0.0")]
187 impl<T: fmt::Debug> fmt::Debug for [T; $N] {
188 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
189 fmt::Debug::fmt(&&self[..], f)
193 #[stable(feature = "rust1", since = "1.0.0")]
194 impl<'a, T> IntoIterator for &'a [T; $N] {
196 type IntoIter = Iter<'a, T>;
198 fn into_iter(self) -> Iter<'a, T> {
203 #[stable(feature = "rust1", since = "1.0.0")]
204 impl<'a, T> IntoIterator for &'a mut [T; $N] {
205 type Item = &'a mut T;
206 type IntoIter = IterMut<'a, T>;
208 fn into_iter(self) -> IterMut<'a, T> {
213 // NOTE: some less important impls are omitted to reduce code bloat
214 __impl_slice_eq1! { [A; $N], [B; $N] }
215 __impl_slice_eq2! { [A; $N], [B] }
216 __impl_slice_eq2! { [A; $N], &'b [B] }
217 __impl_slice_eq2! { [A; $N], &'b mut [B] }
218 // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
219 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
221 #[stable(feature = "rust1", since = "1.0.0")]
222 impl<T:Eq> Eq for [T; $N] { }
224 #[stable(feature = "rust1", since = "1.0.0")]
225 impl<T:PartialOrd> PartialOrd for [T; $N] {
227 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
228 PartialOrd::partial_cmp(&&self[..], &&other[..])
231 fn lt(&self, other: &[T; $N]) -> bool {
232 PartialOrd::lt(&&self[..], &&other[..])
235 fn le(&self, other: &[T; $N]) -> bool {
236 PartialOrd::le(&&self[..], &&other[..])
239 fn ge(&self, other: &[T; $N]) -> bool {
240 PartialOrd::ge(&&self[..], &&other[..])
243 fn gt(&self, other: &[T; $N]) -> bool {
244 PartialOrd::gt(&&self[..], &&other[..])
248 #[stable(feature = "rust1", since = "1.0.0")]
249 impl<T:Ord> Ord for [T; $N] {
251 fn cmp(&self, other: &[T; $N]) -> Ordering {
252 Ord::cmp(&&self[..], &&other[..])
261 10 11 12 13 14 15 16 17 18 19
262 20 21 22 23 24 25 26 27 28 29
266 // The Default impls cannot be generated using the array_impls! macro because
267 // they require array literals.
269 macro_rules! array_impl_default {
270 {$n:expr, $t:ident $($ts:ident)*} => {
271 #[stable(since = "1.4.0", feature = "array_default")]
272 impl<T> Default for [T; $n] where T: Default {
273 fn default() -> [T; $n] {
274 [$t::default(), $($ts::default()),*]
277 array_impl_default!{($n - 1), $($ts)*}
280 #[stable(since = "1.4.0", feature = "array_default")]
281 impl<T> Default for [T; $n] {
282 fn default() -> [T; $n] { [] }
287 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}