diff options
| author | pravic <[email protected]> | 2016-04-12 17:47:49 +0300 |
|---|---|---|
| committer | pravic <[email protected]> | 2016-04-12 17:47:49 +0300 |
| commit | 91d227b219446d3a8b13f5bf7eb87bfc78a8b339 (patch) | |
| tree | 0e438aefd2b3cf07354a68595d5aa4ed73f81f15 /libcore/array.rs | |
| parent | add native import libraries (diff) | |
| download | kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.tar.xz kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.zip | |
add libcore from 2016-04-11 nightly
Diffstat (limited to 'libcore/array.rs')
| -rw-r--r-- | libcore/array.rs | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/libcore/array.rs b/libcore/array.rs new file mode 100644 index 0000000..45fc5ff --- /dev/null +++ b/libcore/array.rs @@ -0,0 +1,244 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementations of things like `Eq` for fixed-length arrays +//! up to a certain length. Eventually we should able to generalize +//! to all lengths. +//! +//! *[See also the array primitive type](../../std/primitive.array.html).* + +#![unstable(feature = "fixed_size_array", + reason = "traits and impls are better expressed through generic \ + integer constants", + issue = "27778")] + +use borrow::{Borrow, BorrowMut}; +use clone::Clone; +use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; +use convert::{AsRef, AsMut}; +use default::Default; +use fmt; +use hash::{Hash, self}; +use iter::IntoIterator; +use marker::{Copy, Sized, Unsize}; +use option::Option; +use slice::{Iter, IterMut, SliceExt}; + +/// Utility trait implemented only on arrays of fixed size +/// +/// This trait can be used to implement other traits on fixed-size arrays +/// without causing much metadata bloat. +/// +/// The trait is marked unsafe in order to restrict implementors to fixed-size +/// arrays. User of this trait can assume that implementors have the exact +/// layout in memory of a fixed size array (for example, for unsafe +/// initialization). +/// +/// Note that the traits AsRef and AsMut provide similar methods for types that +/// may not be fixed-size arrays. Implementors should prefer those traits +/// instead. +pub unsafe trait FixedSizeArray<T> { + /// Converts the array to immutable slice + fn as_slice(&self) -> &[T]; + /// Converts the array to mutable slice + fn as_mut_slice(&mut self) -> &mut [T]; +} + +unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A { + #[inline] + fn as_slice(&self) -> &[T] { + self + } + #[inline] + fn as_mut_slice(&mut self) -> &mut [T] { + self + } +} + +macro_rules! __impl_slice_eq1 { + ($Lhs: ty, $Rhs: ty) => { + __impl_slice_eq1! { $Lhs, $Rhs, Sized } + }; + ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> { + #[inline] + fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } + #[inline] + fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } + } + } +} + +macro_rules! __impl_slice_eq2 { + ($Lhs: ty, $Rhs: ty) => { + __impl_slice_eq2! { $Lhs, $Rhs, Sized } + }; + ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + __impl_slice_eq1!($Lhs, $Rhs, $Bound); + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> { + #[inline] + fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] } + #[inline] + fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] } + } + } +} + +// macro for implementing n-ary tuple functions and operations +macro_rules! array_impls { + ($($N:expr)+) => { + $( + impl<T> AsRef<[T]> for [T; $N] { + #[inline] + fn as_ref(&self) -> &[T] { + &self[..] + } + } + + impl<T> AsMut<[T]> for [T; $N] { + #[inline] + fn as_mut(&mut self) -> &mut [T] { + &mut self[..] + } + } + + #[stable(feature = "array_borrow", since = "1.4.0")] + impl<T> Borrow<[T]> for [T; $N] { + fn borrow(&self) -> &[T] { + self + } + } + + #[stable(feature = "array_borrow", since = "1.4.0")] + impl<T> BorrowMut<[T]> for [T; $N] { + fn borrow_mut(&mut self) -> &mut [T] { + self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Copy> Clone for [T; $N] { + fn clone(&self) -> [T; $N] { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: Hash> Hash for [T; $N] { + fn hash<H: hash::Hasher>(&self, state: &mut H) { + Hash::hash(&self[..], state) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: fmt::Debug> fmt::Debug for [T; $N] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&&self[..], f) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> IntoIterator for &'a [T; $N] { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> IntoIterator for &'a mut [T; $N] { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } + } + + // NOTE: some less important impls are omitted to reduce code bloat + __impl_slice_eq1! { [A; $N], [B; $N] } + __impl_slice_eq2! { [A; $N], [B] } + __impl_slice_eq2! { [A; $N], &'b [B] } + __impl_slice_eq2! { [A; $N], &'b mut [B] } + // __impl_slice_eq2! { [A; $N], &'b [B; $N] } + // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Eq> Eq for [T; $N] { } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:PartialOrd> PartialOrd for [T; $N] { + #[inline] + fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { + PartialOrd::partial_cmp(&&self[..], &&other[..]) + } + #[inline] + fn lt(&self, other: &[T; $N]) -> bool { + PartialOrd::lt(&&self[..], &&other[..]) + } + #[inline] + fn le(&self, other: &[T; $N]) -> bool { + PartialOrd::le(&&self[..], &&other[..]) + } + #[inline] + fn ge(&self, other: &[T; $N]) -> bool { + PartialOrd::ge(&&self[..], &&other[..]) + } + #[inline] + fn gt(&self, other: &[T; $N]) -> bool { + PartialOrd::gt(&&self[..], &&other[..]) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Ord> Ord for [T; $N] { + #[inline] + fn cmp(&self, other: &[T; $N]) -> Ordering { + Ord::cmp(&&self[..], &&other[..]) + } + } + )+ + } +} + +array_impls! { + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 +} + +// The Default impls cannot be generated using the array_impls! macro because +// they require array literals. + +macro_rules! array_impl_default { + {$n:expr, $t:ident $($ts:ident)*} => { + #[stable(since = "1.4.0", feature = "array_default")] + impl<T> Default for [T; $n] where T: Default { + fn default() -> [T; $n] { + [$t::default(), $($ts::default()),*] + } + } + array_impl_default!{($n - 1), $($ts)*} + }; + {$n:expr,} => { + #[stable(since = "1.4.0", feature = "array_default")] + impl<T> Default for [T; $n] { + fn default() -> [T; $n] { [] } + } + }; +} + +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} |