125 lines
3.8 KiB
Rust
125 lines
3.8 KiB
Rust
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#[macro_escape];
|
|
|
|
use std::slice::{Items, MutItems};
|
|
|
|
pub trait Array
|
|
<
|
|
T: Clone,
|
|
Slice
|
|
>
|
|
{
|
|
fn i<'a>(&'a self, i: uint) -> &'a T;
|
|
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut T;
|
|
fn as_slice<'a>(&'a self) -> &'a Slice;
|
|
fn as_mut_slice<'a>(&'a mut self) -> &'a mut Slice;
|
|
fn from_slice(slice: Slice) -> Self;
|
|
fn build(builder: |i: uint| -> T) -> Self;
|
|
fn iter<'a>(&'a self) -> Items<'a, T>;
|
|
fn mut_iter<'a>(&'a mut self) -> MutItems<'a, T>;
|
|
|
|
/// Swap two elements of the type in place.
|
|
#[inline]
|
|
fn swap(&mut self, a: uint, b: uint) {
|
|
let tmp = self.i(a).clone();
|
|
*self.mut_i(a) = self.i(b).clone();
|
|
*self.mut_i(b) = tmp;
|
|
}
|
|
|
|
fn fold(&self, f: |&T, &T| -> T) -> T;
|
|
fn each_mut(&mut self, f: |i: uint, x: &mut T|);
|
|
}
|
|
|
|
macro_rules! array(
|
|
(impl<$S:ident> $Self:ty -> [$T:ty, ..$n:expr] $_n:ident) => (
|
|
impl<$S: Clone> Array<$T, [$T,..$n]> for $Self {
|
|
#[inline]
|
|
fn i<'a>(&'a self, i: uint) -> &'a $T {
|
|
&'a self.as_slice()[i]
|
|
}
|
|
|
|
#[inline]
|
|
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut $T {
|
|
&'a mut self.as_mut_slice()[i]
|
|
}
|
|
|
|
#[inline]
|
|
fn as_slice<'a>(&'a self) -> &'a [$T,..$n] {
|
|
unsafe { ::std::cast::transmute(self) }
|
|
}
|
|
|
|
#[inline]
|
|
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [$T,..$n] {
|
|
unsafe { ::std::cast::transmute(self) }
|
|
}
|
|
|
|
#[inline]
|
|
fn from_slice(slice: [$T,..$n]) -> $Self {
|
|
unsafe { ::std::cast::transmute(slice) }
|
|
}
|
|
|
|
#[inline]
|
|
fn build(builder: |i: uint| -> $T) -> $Self {
|
|
Array::from_slice(gen_builder!($_n))
|
|
}
|
|
|
|
#[inline]
|
|
fn iter<'a>(&'a self) -> ::std::slice::Items<'a, $T> {
|
|
self.as_slice().iter()
|
|
}
|
|
|
|
#[inline]
|
|
fn mut_iter<'a>(&'a mut self) -> ::std::slice::MutItems<'a, $T> {
|
|
self.as_mut_slice().mut_iter()
|
|
}
|
|
|
|
#[inline]
|
|
fn fold(&self, f: |&$T, &$T| -> $T) -> $T {
|
|
gen_fold!($_n)
|
|
}
|
|
|
|
#[inline]
|
|
fn each_mut(&mut self, f: |i: uint, x: &mut $T|) {
|
|
gen_each_mut!($_n)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
#[inline]
|
|
pub fn build<T: Clone, Slice, A: Array<T, Slice>>(builder: |i: uint| -> T) -> A {
|
|
Array::build(builder)
|
|
}
|
|
|
|
macro_rules! gen_builder(
|
|
(_2) => ({ [builder(0), builder(1)] });
|
|
(_3) => ({ [builder(0), builder(1), builder(2)] });
|
|
(_4) => ({ [builder(0), builder(1), builder(2), builder(3)] });
|
|
)
|
|
|
|
macro_rules! gen_fold(
|
|
(_2) => ({ f(self.i(0), self.i(1)) });
|
|
(_3) => ({ f(&f(self.i(0), self.i(1)), self.i(2)) });
|
|
(_4) => ({ f(&f(&f(self.i(0), self.i(1)), self.i(2)), self.i(3)) });
|
|
)
|
|
|
|
macro_rules! gen_each_mut(
|
|
(_2) => ({ f(0, self.mut_i(0)); f(1, self.mut_i(1)); });
|
|
(_3) => ({ f(0, self.mut_i(0)); f(1, self.mut_i(1)); f(2, self.mut_i(2)); });
|
|
(_4) => ({ f(0, self.mut_i(0)); f(1, self.mut_i(1)); f(2, self.mut_i(2)); f(3, self.mut_i(3)); });
|
|
)
|
|
|