rust/src/libcore/tuple.rs

263 lines
8.0 KiB
Rust
Raw Normal View History

// Copyright 2012 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.
//! Operations on tuples
2014-05-26 03:34:51 -05:00
//!
//! To access a single element of a tuple one can use the following
//! methods:
//!
//! * `valN` - returns a value of _N_-th element
//! * `refN` - returns a reference to _N_-th element
//! * `mutN` - returns a mutable reference to _N_-th element
//!
//! Indexing starts from zero, so `val0` returns first value, `val1`
//! returns second value, and so on. In general, a tuple with _S_
//! elements provides aforementioned methods suffixed with numbers
//! from `0` to `S-1`. Traits which contain these methods are
//! implemented for tuples with up to 12 elements.
//!
//! If every type inside a tuple implements one of the following
//! traits, then a tuple itself also implements it.
//!
//! * `Clone`
//! * `PartialEq`
//! * `Eq`
//! * `PartialOrd`
//! * `Ord`
2014-05-26 03:34:51 -05:00
//! * `Default`
std: Stabilize unit, bool, ty, tuple, arc, any This commit applies stability attributes to the contents of these modules, summarized here: * The `unit` and `bool` modules have become #[unstable] as they are purely meant for documentation purposes and are candidates for removal. * The `ty` module has been deprecated, and the inner `Unsafe` type has been renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field has been removed as the compiler now always infers `UnsafeCell` to be invariant. The `new` method i stable, but the `value` field, `get` and `unwrap` methods are all unstable. * The `tuple` module has its name as stable, the naming of the `TupleN` traits as stable while the methods are all #[unstable]. The other impls in the module have appropriate stability for the corresponding trait. * The `arc` module has received the exact same treatment as the `rc` module previously did. * The `any` module has its name as stable. The `Any` trait is also stable, with a new private supertrait which now contains the `get_type_id` method. This is to make the method a private implementation detail rather than a public-facing detail. The two extension traits in the module are marked #[unstable] as they will not be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods have been renamed to downcast_{mut,ref} and are #[unstable]. The extension trait `BoxAny` has been clarified as to why it is unstable as it will not be necessary with DST. This is a breaking change because the `marker1` field was removed from the `UnsafeCell` type. To deal with this change, you can simply delete the field and only specify the value of the `data` field in static initializers. [breaking-change]
2014-07-23 21:10:12 -05:00
#![stable]
std: Stabilize unit, bool, ty, tuple, arc, any This commit applies stability attributes to the contents of these modules, summarized here: * The `unit` and `bool` modules have become #[unstable] as they are purely meant for documentation purposes and are candidates for removal. * The `ty` module has been deprecated, and the inner `Unsafe` type has been renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field has been removed as the compiler now always infers `UnsafeCell` to be invariant. The `new` method i stable, but the `value` field, `get` and `unwrap` methods are all unstable. * The `tuple` module has its name as stable, the naming of the `TupleN` traits as stable while the methods are all #[unstable]. The other impls in the module have appropriate stability for the corresponding trait. * The `arc` module has received the exact same treatment as the `rc` module previously did. * The `any` module has its name as stable. The `Any` trait is also stable, with a new private supertrait which now contains the `get_type_id` method. This is to make the method a private implementation detail rather than a public-facing detail. The two extension traits in the module are marked #[unstable] as they will not be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods have been renamed to downcast_{mut,ref} and are #[unstable]. The extension trait `BoxAny` has been clarified as to why it is unstable as it will not be necessary with DST. This is a breaking change because the `marker1` field was removed from the `UnsafeCell` type. To deal with this change, you can simply delete the field and only specify the value of the `data` field in static initializers. [breaking-change]
2014-07-23 21:10:12 -05:00
#[unstable = "this is just a documentation module and should not be part \
of the public api"]
2014-07-01 19:21:15 -05:00
2013-07-02 14:47:32 -05:00
use clone::Clone;
use cmp::*;
use cmp::Ordering::*;
use default::Default;
use option::Option;
use option::Option::Some;
2014-12-09 10:44:56 -06:00
// FIXME(#19630) Remove this work-around
macro_rules! e {
($e:expr) => { $e }
}
// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
($(
$Tuple:ident {
2014-12-09 10:44:56 -06:00
$(($valN:ident, $refN:ident, $mutN:ident, $idx:tt) -> $T:ident)+
}
)+) => {
$(
#[stable]
impl<$($T:Clone),+> Clone for ($($T,)+) {
fn clone(&self) -> ($($T,)+) {
2014-12-09 10:44:56 -06:00
($(e!(self.$idx.clone()),)+)
}
}
2012-08-27 18:26:35 -05:00
#[stable]
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
#[inline]
fn eq(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
e!($(self.$idx == other.$idx)&&+)
}
#[inline]
fn ne(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
e!($(self.$idx != other.$idx)||+)
}
}
2012-08-27 18:26:35 -05:00
#[stable]
impl<$($T:Eq),+> Eq for ($($T,)+) {}
#[stable]
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
#[inline]
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
2014-12-09 10:44:56 -06:00
lexical_partial_cmp!($(self.$idx, other.$idx),+)
}
#[inline]
fn lt(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
lexical_ord!(lt, $(self.$idx, other.$idx),+)
}
#[inline]
fn le(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
lexical_ord!(le, $(self.$idx, other.$idx),+)
}
#[inline]
fn ge(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
lexical_ord!(ge, $(self.$idx, other.$idx),+)
}
#[inline]
fn gt(&self, other: &($($T,)+)) -> bool {
2014-12-09 10:44:56 -06:00
lexical_ord!(gt, $(self.$idx, other.$idx),+)
}
}
#[stable]
impl<$($T:Ord),+> Ord for ($($T,)+) {
#[inline]
fn cmp(&self, other: &($($T,)+)) -> Ordering {
2014-12-09 10:44:56 -06:00
lexical_cmp!($(self.$idx, other.$idx),+)
}
}
std: Stabilize unit, bool, ty, tuple, arc, any This commit applies stability attributes to the contents of these modules, summarized here: * The `unit` and `bool` modules have become #[unstable] as they are purely meant for documentation purposes and are candidates for removal. * The `ty` module has been deprecated, and the inner `Unsafe` type has been renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field has been removed as the compiler now always infers `UnsafeCell` to be invariant. The `new` method i stable, but the `value` field, `get` and `unwrap` methods are all unstable. * The `tuple` module has its name as stable, the naming of the `TupleN` traits as stable while the methods are all #[unstable]. The other impls in the module have appropriate stability for the corresponding trait. * The `arc` module has received the exact same treatment as the `rc` module previously did. * The `any` module has its name as stable. The `Any` trait is also stable, with a new private supertrait which now contains the `get_type_id` method. This is to make the method a private implementation detail rather than a public-facing detail. The two extension traits in the module are marked #[unstable] as they will not be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods have been renamed to downcast_{mut,ref} and are #[unstable]. The extension trait `BoxAny` has been clarified as to why it is unstable as it will not be necessary with DST. This is a breaking change because the `marker1` field was removed from the `UnsafeCell` type. To deal with this change, you can simply delete the field and only specify the value of the `data` field in static initializers. [breaking-change]
2014-07-23 21:10:12 -05:00
#[stable]
impl<$($T:Default),+> Default for ($($T,)+) {
#[stable]
#[inline]
fn default() -> ($($T,)+) {
($({ let x: $T = Default::default(); x},)+)
2013-09-11 23:49:25 -05:00
}
}
)+
}
}
// Constructs an expression that performs a lexical ordering using method $rel.
// The values are interleaved, so the macro invocation for
// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
// a3, b3)` (and similarly for `lexical_cmp`)
macro_rules! lexical_ord {
($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
2014-12-09 10:44:56 -06:00
if $a != $b { lexical_ord!($rel, $a, $b) }
else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
};
2014-12-09 10:44:56 -06:00
($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
}
macro_rules! lexical_partial_cmp {
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
2014-12-09 10:44:56 -06:00
match ($a).partial_cmp(&$b) {
Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
ordering => ordering
}
};
2014-12-09 10:44:56 -06:00
($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
}
macro_rules! lexical_cmp {
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
2014-12-09 10:44:56 -06:00
match ($a).cmp(&$b) {
Equal => lexical_cmp!($($rest_a, $rest_b),+),
ordering => ordering
}
};
2014-12-09 10:44:56 -06:00
($a:expr, $b:expr) => { ($a).cmp(&$b) };
}
tuple_impls! {
Tuple1 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
}
Tuple2 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
}
Tuple3 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
}
Tuple4 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
}
Tuple5 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
}
Tuple6 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
}
Tuple7 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
}
Tuple8 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
(val7, ref7, mut7, 7) -> H
}
Tuple9 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
(val7, ref7, mut7, 7) -> H
(val8, ref8, mut8, 8) -> I
}
Tuple10 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
(val7, ref7, mut7, 7) -> H
(val8, ref8, mut8, 8) -> I
(val9, ref9, mut9, 9) -> J
}
Tuple11 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
(val7, ref7, mut7, 7) -> H
(val8, ref8, mut8, 8) -> I
(val9, ref9, mut9, 9) -> J
(val10, ref10, mut10, 10) -> K
}
Tuple12 {
2014-12-09 10:44:56 -06:00
(val0, ref0, mut0, 0) -> A
(val1, ref1, mut1, 1) -> B
(val2, ref2, mut2, 2) -> C
(val3, ref3, mut3, 3) -> D
(val4, ref4, mut4, 4) -> E
(val5, ref5, mut5, 5) -> F
(val6, ref6, mut6, 6) -> G
(val7, ref7, mut7, 7) -> H
(val8, ref8, mut8, 8) -> I
(val9, ref9, mut9, 9) -> J
(val10, ref10, mut10, 10) -> K
(val11, ref11, mut11, 11) -> L
}
}