vec.rs 62.5 KB
Newer Older
1
//! Vectors
B
Brian Anderson 已提交
2

3 4
import option::{some, none};
import ptr::addr_of;
5
import libc::size_t;
6

7
export append;
E
Eric Holk 已提交
8
export append_one;
E
Eric Holk 已提交
9
export consume;
10 11 12 13 14
export init_op;
export is_empty;
export is_not_empty;
export same_length;
export reserve;
15
export reserve_at_least;
B
Brian Anderson 已提交
16
export capacity;
17
export len;
18 19
export from_fn;
export from_elem;
20 21 22 23
export to_mut;
export from_mut;
export head;
export tail;
24
export tailn;
25 26 27 28
export init;
export last;
export last_opt;
export slice;
29
export view;
30 31 32 33 34
export split;
export splitn;
export rsplit;
export rsplitn;
export shift;
J
Jeff Olson 已提交
35
export unshift;
36
export pop;
37
export push, push_all, push_all_move;
38 39 40 41
export grow;
export grow_fn;
export grow_set;
export map;
42
export mapi;
43
export map2;
E
Eric Holk 已提交
44
export map_consume;
45
export flat_map;
46 47 48 49 50 51 52 53 54
export filter_map;
export filter;
export concat;
export connect;
export foldl;
export foldr;
export any;
export any2;
export all;
E
Eric Holk 已提交
55
export alli;
56 57 58 59
export all2;
export contains;
export count;
export find;
60
export find_between;
61
export rfind;
62
export rfind_between;
63
export position_elem;
64
export position;
65
export position_between;
66
export position_elem;
67
export rposition;
68
export rposition_between;
69 70 71 72 73
export unzip;
export zip;
export swap;
export reverse;
export reversed;
74
export iter, iter_between, each, eachi;
75 76 77 78 79 80 81 82
export iter2;
export iteri;
export riter;
export riteri;
export permute;
export windowed;
export as_buf;
export as_mut_buf;
83
export unpack_slice;
84
export unpack_const_slice;
85 86
export unsafe;
export u8;
87
export extensions;
88

89
#[abi = "cdecl"]
90
extern mod rustrt {
91 92 93 94 95 96
    fn vec_reserve_shared(++t: *sys::type_desc,
                          ++v: **unsafe::vec_repr,
                          ++n: libc::size_t);
    fn vec_from_buf_shared(++t: *sys::type_desc,
                           ++ptr: *(),
                           ++count: libc::size_t) -> *unsafe::vec_repr;
97 98
}

E
Eric Holk 已提交
99
#[abi = "rust-intrinsic"]
100
extern mod rusti {
E
Eric Holk 已提交
101 102 103
    fn move_val_init<T>(&dst: T, -src: T);
}

104
/// A function used to initialize the elements of a vector
N
Niko Matsakis 已提交
105
type init_op<T> = fn(uint) -> T;
106

107
/// Returns true if a vector contains no elements
108
pure fn is_empty<T>(v: &[const T]) -> bool {
B
Brian Anderson 已提交
109
    unpack_const_slice(v, |_p, len| len == 0u)
110 111
}

112
/// Returns true if a vector contains some elements
113
pure fn is_not_empty<T>(v: &[const T]) -> bool {
B
Brian Anderson 已提交
114
    unpack_const_slice(v, |_p, len| len > 0u)
115
}
116

117
/// Returns true if two vectors have the same length
118
pure fn same_length<T, U>(xs: &[const T], ys: &[const U]) -> bool {
119
    len(xs) == len(ys)
120 121
}

122 123 124 125 126 127 128 129 130 131 132
/**
 * Reserves capacity for exactly `n` elements in the given vector.
 *
 * If the capacity for `v` is already equal to or greater than the requested
 * capacity, then no action is taken.
 *
 * # Arguments
 *
 * * v - A vector
 * * n - The number of elements to reserve space for
 */
133
fn reserve<T>(&v: ~[const T], n: uint) {
134 135
    // Only make the (slow) call into the runtime if we have to
    if capacity(v) < n {
136
        let ptr = ptr::addr_of(v) as **unsafe::vec_repr;
137 138
        rustrt::vec_reserve_shared(sys::get_type_desc::<T>(),
                                   ptr, n as size_t);
139
    }
140 141
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
/**
 * Reserves capacity for at least `n` elements in the given vector.
 *
 * This function will over-allocate in order to amortize the allocation costs
 * in scenarios where the caller may need to repeatedly reserve additional
 * space.
 *
 * If the capacity for `v` is already equal to or greater than the requested
 * capacity, then no action is taken.
 *
 * # Arguments
 *
 * * v - A vector
 * * n - The number of elements to reserve space for
 */
157
fn reserve_at_least<T>(&v: ~[const T], n: uint) {
158 159 160
    reserve(v, uint::next_power_of_two(n));
}

161
/// Returns the number of elements the vector can hold without reallocating
162
#[inline(always)]
163
pure fn capacity<T>(&&v: ~[const T]) -> uint {
164 165 166 167
    unsafe {
        let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        (**repr).alloc / sys::size_of::<T>()
    }
B
Brian Anderson 已提交
168 169
}

170
/// Returns the length of a vector
171
#[inline(always)]
172
pure fn len<T>(&&v: &[const T]) -> uint {
B
Brian Anderson 已提交
173
    unpack_const_slice(v, |_p, len| len)
174
}
175

176 177 178 179 180 181
/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
182 183
pure fn from_fn<T>(n_elts: uint, op: init_op<T>) -> ~[T] {
    let mut v = ~[];
184
    unchecked{reserve(v, n_elts);}
185
    let mut i: uint = 0u;
186
    while i < n_elts unsafe { push(v, op(i)); i += 1u; }
187 188 189
    ret v;
}

190 191 192 193 194 195
/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
196 197
pure fn from_elem<T: copy>(n_elts: uint, t: T) -> ~[T] {
    let mut v = ~[];
198
    unchecked{reserve(v, n_elts)}
199
    let mut i: uint = 0u;
200 201 202
    unsafe { // because push is impure
        while i < n_elts { push(v, t); i += 1u; }
    }
203 204 205
    ret v;
}

206
/// Produces a mut vector from an immutable vector.
207
fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
208
    unsafe { ::unsafe::transmute(v) }
209 210
}

211
/// Produces an immutable vector from a mut vector.
212
fn from_mut<T>(+v: ~[mut T]) -> ~[T] {
213
    unsafe { ::unsafe::transmute(v) }
214 215 216 217
}

// Accessors

218
/// Returns the first element of a vector
219
pure fn head<T: copy>(v: &[const T]) -> T { v[0] }
220

221
/// Returns a vector containing all but the first element of a slice
222
pure fn tail<T: copy>(v: &[const T]) -> ~[T] {
223 224 225
    ret slice(v, 1u, len(v));
}

226 227 228 229
/**
 * Returns a vector containing all but the first `n` \
 * elements of a slice
 */
230
pure fn tailn<T: copy>(v: &[const T], n: uint) -> ~[T] {
231 232 233
    slice(v, n, len(v))
}

234
/// Returns a vector containing all but the last element of a slice
235
pure fn init<T: copy>(v: &[const T]) -> ~[T] {
236 237 238 239
    assert len(v) != 0u;
    slice(v, 0u, len(v) - 1u)
}

240
/// Returns the last element of the slice `v`, failing if the slice is empty.
241
pure fn last<T: copy>(v: &[const T]) -> T {
242 243
    if len(v) == 0u { fail "last_unsafe: empty vector" }
    v[len(v) - 1u]
244 245
}

246 247 248 249
/**
 * Returns `some(x)` where `x` is the last element of the slice `v`,
 * or `none` if the vector is empty.
 */
250
pure fn last_opt<T: copy>(v: &[const T]) -> option<T> {
251
    if len(v) == 0u { ret none; }
252
    some(v[len(v) - 1u])
T
Tim Chevalier 已提交
253
}
254

255
/// Returns a copy of the elements from [`start`..`end`) from `v`.
256
pure fn slice<T: copy>(v: &[const T], start: uint, end: uint) -> ~[T] {
257 258
    assert (start <= end);
    assert (end <= len(v));
259
    let mut result = ~[];
260 261 262
    unchecked {
        push_all(result, view(v, start, end));
    }
263 264 265
    ret result;
}

E
Eric Holk 已提交
266 267
#[doc = "Return a slice that points into another slice."]
pure fn view<T>(v: &[const T], start: uint, end: uint) -> &a.[T] {
268 269
    assert (start <= end);
    assert (end <= len(v));
B
Brian Anderson 已提交
270
    do unpack_slice(v) |p, _len| {
271 272 273 274 275 276 277
        unsafe {
            ::unsafe::reinterpret_cast(
                (ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
        }
    }
}

278
/// Split the vector `v` by applying each element against the predicate `f`.
279
fn split<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[~[T]] {
280
    let ln = len(v);
281
    if (ln == 0u) { ret ~[] }
282

283
    let mut start = 0u;
284
    let mut result = ~[];
285
    while start < ln {
286
        alt position_between(v, start, ln, f) {
287 288 289 290 291 292 293 294 295 296 297
          none { break }
          some(i) {
            push(result, slice(v, start, i));
            start = i + 1u;
          }
        }
    }
    push(result, slice(v, start, ln));
    result
}

298 299 300 301
/**
 * Split the vector `v` by applying each element against the predicate `f` up
 * to `n` times.
 */
302
fn splitn<T: copy>(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] {
303
    let ln = len(v);
304
    if (ln == 0u) { ret ~[] }
305

306 307
    let mut start = 0u;
    let mut count = n;
308
    let mut result = ~[];
309
    while start < ln && count > 0u {
310
        alt position_between(v, start, ln, f) {
311 312 313 314 315 316 317 318 319 320 321 322 323
          none { break }
          some(i) {
            push(result, slice(v, start, i));
            // Make sure to skip the separator.
            start = i + 1u;
            count -= 1u;
          }
        }
    }
    push(result, slice(v, start, ln));
    result
}

324 325 326 327
/**
 * Reverse split the vector `v` by applying each element against the predicate
 * `f`.
 */
328
fn rsplit<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[~[T]] {
329
    let ln = len(v);
330
    if (ln == 0u) { ret ~[] }
331

332
    let mut end = ln;
333
    let mut result = ~[];
334
    while end > 0u {
335
        alt rposition_between(v, 0u, end, f) {
336 337 338 339 340 341 342 343 344 345 346
          none { break }
          some(i) {
            push(result, slice(v, i + 1u, end));
            end = i;
          }
        }
    }
    push(result, slice(v, 0u, end));
    reversed(result)
}

347 348 349 350
/**
 * Reverse split the vector `v` by applying each element against the predicate
 * `f` up to `n times.
 */
351
fn rsplitn<T: copy>(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] {
352
    let ln = len(v);
353
    if (ln == 0u) { ret ~[] }
354

355 356
    let mut end = ln;
    let mut count = n;
357
    let mut result = ~[];
358
    while end > 0u && count > 0u {
359
        alt rposition_between(v, 0u, end, f) {
360 361 362 363 364 365 366 367 368 369 370 371
          none { break }
          some(i) {
            push(result, slice(v, i + 1u, end));
            // Make sure to skip the separator.
            end = i;
            count -= 1u;
          }
        }
    }
    push(result, slice(v, 0u, end));
    reversed(result)
}
372 373 374

// Mutators

375
/// Removes the first element from a vector and return it
376
fn shift<T>(&v: ~[T]) -> T {
377
    let ln = len::<T>(v);
E
Eric Holk 已提交
378
    assert (ln > 0);
379

380
    let mut vv = ~[];
381 382 383
    v <-> vv;

    unsafe {
384 385 386
        let mut rr;
        {
            let vv = unsafe::to_ptr(vv);
E
Eric Holk 已提交
387
            rr <- *vv;
388

E
Eric Holk 已提交
389
            for uint::range(1, ln) |i| {
390 391 392
                let r <- *ptr::offset(vv, i);
                push(v, r);
            }
393
        }
E
Eric Holk 已提交
394
        unsafe::set_len(vv, 0);
395

396
        rr
397
    }
B
Brian Anderson 已提交
398 399
}

400
/// Prepend an element to the vector
401 402
fn unshift<T>(&v: ~[T], +x: T) {
    let mut vv = ~[x];
E
Eric Holk 已提交
403 404 405 406 407 408
    v <-> vv;
    while len(vv) > 0 {
        push(v, shift(vv));
    }
}

E
Eric Holk 已提交
409 410 411 412 413 414 415 416 417 418 419
fn consume<T>(+v: ~[T], f: fn(uint, +T)) unsafe {
    do unpack_slice(v) |p, ln| {
        for uint::range(0, ln) |i| {
            let x <- *ptr::offset(p, i);
            f(i, x);
        }
    }

    unsafe::set_len(v, 0);
}

420
/// Remove the last element from a vector and return it
421
fn pop<T>(&v: ~[const T]) -> T {
422
    let ln = len(v);
M
Marijn Haverbeke 已提交
423 424
    assert ln > 0u;
    let valptr = ptr::mut_addr_of(v[ln - 1u]);
425 426 427 428 429
    unsafe {
        let val <- *valptr;
        unsafe::set_len(v, ln - 1u);
        val
    }
430 431
}

432
/// Append an element to a vector
433
#[inline(always)]
434
fn push<T>(&v: ~[const T], +initval: T) {
435
    unsafe {
E
Eric Holk 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
        let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        let fill = (**repr).fill;
        if (**repr).alloc > fill {
            let sz = sys::size_of::<T>();
            (**repr).fill += sz;
            let p = ptr::addr_of((**repr).data);
            let p = ptr::offset(p, fill) as *mut T;
            rusti::move_val_init(*p, initval);
        }
        else {
            push_slow(v, initval);
        }
    }
}

451
fn push_slow<T>(&v: ~[const T], +initval: T) {
E
Eric Holk 已提交
452 453
    unsafe {
        let ln = v.len();
454
        reserve_at_least(v, ln + 1u);
E
Eric Holk 已提交
455 456 457 458 459 460 461
        let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        let fill = (**repr).fill;
        let sz = sys::size_of::<T>();
        (**repr).fill += sz;
        let p = ptr::addr_of((**repr).data);
        let p = ptr::offset(p, fill) as *mut T;
        rusti::move_val_init(*p, initval);
462
    }
E
Erick Tryzelaar 已提交
463 464
}

465 466
// Unchecked vector indexing
#[inline(always)]
467
unsafe fn ref<T: copy>(v: &[const T], i: uint) -> T {
B
Brian Anderson 已提交
468
    unpack_slice(v, |p, _len| *ptr::offset(p, i))
469 470
}

471
#[inline(always)]
472
fn push_all<T: copy>(&v: ~[const T], rhs: &[const T]) {
473
    reserve(v, v.len() + rhs.len());
474

B
Brian Anderson 已提交
475
    for uint::range(0u, rhs.len()) |i| {
476
        push(v, unsafe { ref(rhs, i) })
477 478
    }
}
479

480
#[inline(always)]
481
fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
482 483
    reserve(v, v.len() + rhs.len());
    unsafe {
B
Brian Anderson 已提交
484 485
        do unpack_slice(rhs) |p, len| {
            for uint::range(0, len) |i| {
486 487 488 489 490 491 492 493
                let x <- *ptr::offset(p, i);
                push(v, x);
            }
        }
        unsafe::set_len(rhs, 0);
    }
}

494
// Appending
495
#[inline(always)]
496
pure fn append<T: copy>(+lhs: ~[T], rhs: &[const T]) -> ~[T] {
497
    let mut v <- lhs;
498 499
    unchecked {
        push_all(v, rhs);
500 501 502 503
    }
    ret v;
}

E
Eric Holk 已提交
504
#[inline(always)]
505
pure fn append_one<T>(+lhs: ~[T], +x: T) -> ~[T] {
E
Eric Holk 已提交
506 507 508 509 510
    let mut v <- lhs;
    unchecked { push(v, x); }
    v
}

511
#[inline(always)]
512 513
pure fn append_mut<T: copy>(lhs: &[mut T], rhs: &[const T]) -> ~[mut T] {
    let mut v = ~[mut];
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
    let mut i = 0u;
    while i < lhs.len() {
        unsafe { // This is impure, but it appears pure to the caller.
            push(v, lhs[i]);
        }
        i += 1u;
    }
    i = 0u;
    while i < rhs.len() {
        unsafe { // This is impure, but it appears pure to the caller.
            push(v, rhs[i]);
        }
        i += 1u;
    }
    ret v;
}
530

531 532 533 534 535 536 537 538 539
/**
 * Expands a vector in place, initializing the new elements to a given value
 *
 * # Arguments
 *
 * * v - The vector to grow
 * * n - The number of elements to add
 * * initval - The value for the new elements
 */
540
fn grow<T: copy>(&v: ~[const T], n: uint, initval: T) {
541
    reserve_at_least(v, len(v) + n);
542
    let mut i: uint = 0u;
543 544

    while i < n { push(v, initval); i += 1u; }
545 546
}

547 548 549 550 551 552 553 554 555 556 557 558 559
/**
 * Expands a vector in place, initializing the new elements to the result of
 * a function
 *
 * Function `init_op` is called `n` times with the values [0..`n`)
 *
 * # Arguments
 *
 * * v - The vector to grow
 * * n - The number of elements to add
 * * init_op - A function to call to retreive each appended element's
 *             value
 */
560
fn grow_fn<T>(&v: ~[const T], n: uint, op: init_op<T>) {
561
    reserve_at_least(v, len(v) + n);
562
    let mut i: uint = 0u;
563
    while i < n { push(v, op(i)); i += 1u; }
564 565
}

566 567 568 569 570 571 572 573
/**
 * Sets the value of a vector element at a given index, growing the vector as
 * needed
 *
 * Sets the element at position `index` to `val`. If `index` is past the end
 * of the vector, expands the vector by replicating `initval` to fill the
 * intervening space.
 */
E
Eric Holk 已提交
574
#[inline(always)]
575
fn grow_set<T: copy>(&v: ~[mut T], index: uint, initval: T, val: T) {
576
    if index >= len(v) { grow(v, index - len(v) + 1u, initval); }
577 578 579 580 581 582
    v[index] = val;
}


// Functional utilities

583
/// Apply a function to each element of a vector and return the results
584 585
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> ~[U] {
    let mut result = ~[];
586
    unchecked{reserve(result, len(v));}
B
Brian Anderson 已提交
587
    for each(v) |elem| { unsafe { push(result, f(elem)); } }
588 589 590
    ret result;
}

E
Eric Holk 已提交
591 592 593 594 595 596 597 598
fn map_consume<T, U>(+v: ~[T], f: fn(+T) -> U) -> ~[U] {
    let mut result = ~[];
    do consume(v) |_i, x| {
        vec::push(result, f(x));
    }
    result
}

599
/// Apply a function to each element of a vector and return the results
600 601
pure fn mapi<T, U>(v: &[T], f: fn(uint, T) -> U) -> ~[U] {
    let mut result = ~[];
602
    unchecked{reserve(result, len(v));}
B
Brian Anderson 已提交
603
    for eachi(v) |i, elem| { unsafe { push(result, f(i, elem)); } }
604 605 606
    ret result;
}

607 608 609 610
/**
 * Apply a function to each element of a vector and return a concatenation
 * of each result vector
 */
611 612
pure fn flat_map<T, U>(v: &[T], f: fn(T) -> ~[U]) -> ~[U] {
    let mut result = ~[];
B
Brian Anderson 已提交
613
    for each(v) |elem| { unchecked{ push_all_move(result, f(elem)); } }
614 615 616
    ret result;
}

617
/// Apply a function to each pair of elements and return the results
618 619
pure fn map2<T: copy, U: copy, V>(v0: &[T], v1: &[U],
                                  f: fn(T, U) -> V) -> ~[V] {
620 621
    let v0_len = len(v0);
    if v0_len != len(v1) { fail; }
622
    let mut u: ~[V] = ~[];
623
    let mut i = 0u;
624 625 626 627
    while i < v0_len {
        unsafe { push(u, f(copy v0[i], copy v1[i])) };
        i += 1u;
    }
628 629 630
    ret u;
}

631 632 633 634 635 636
/**
 * Apply a function to each element of a vector and return the results
 *
 * If function `f` returns `none` then that element is excluded from
 * the resulting vector.
 */
637 638 639
pure fn filter_map<T, U: copy>(v: &[T], f: fn(T) -> option<U>)
    -> ~[U] {
    let mut result = ~[];
B
Brian Anderson 已提交
640
    for each(v) |elem| {
641
        alt f(elem) {
642
          none {/* no-op */ }
643
          some(result_elem) { unsafe { push(result, result_elem); } }
644 645 646 647 648
        }
    }
    ret result;
}

649 650 651 652 653 654 655
/**
 * Construct a new vector from the elements of a vector for which some
 * predicate holds.
 *
 * Apply function `f` to each element of `v` and return a vector containing
 * only those elements for which `f` returned true.
 */
656 657
pure fn filter<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[T] {
    let mut result = ~[];
B
Brian Anderson 已提交
658
    for each(v) |elem| {
659
        if f(elem) { unsafe { push(result, elem); } }
660 661 662 663
    }
    ret result;
}

664 665 666 667 668
/**
 * Concatenate a vector of vectors.
 *
 * Flattens a vector of vectors of T into a single vector of T.
 */
669 670
pure fn concat<T: copy>(v: &[[T]/~]) -> ~[T] {
    let mut r = ~[];
B
Brian Anderson 已提交
671
    for each(v) |inner| { unsafe { push_all(r, inner); } }
672
    ret r;
673 674
}

675
/// Concatenate a vector of vectors, placing a given separator between each
676 677
pure fn connect<T: copy>(v: &[[T]/~], sep: T) -> ~[T] {
    let mut r: ~[T] = ~[];
678
    let mut first = true;
B
Brian Anderson 已提交
679
    for each(v) |inner| {
680
        if first { first = false; } else { unsafe { push(r, sep); } }
681
        unchecked { push_all(r, inner) };
682
    }
683
    ret r;
684 685
}

686
/// Reduce a vector from left to right
687
pure fn foldl<T: copy, U>(z: T, v: &[U], p: fn(T, U) -> T) -> T {
688
    let mut accum = z;
B
Brian Anderson 已提交
689
    do iter(v) |elt| {
690 691 692 693 694
        accum = p(accum, elt);
    }
    ret accum;
}

695
/// Reduce a vector from right to left
696
pure fn foldr<T, U: copy>(v: &[T], z: U, p: fn(T, U) -> U) -> U {
697
    let mut accum = z;
B
Brian Anderson 已提交
698
    do riter(v) |elt| {
699 700 701 702 703
        accum = p(elt, accum);
    }
    ret accum;
}

704 705 706 707 708
/**
 * Return true if a predicate matches any elements
 *
 * If the vector contains no elements then false is returned.
 */
709
pure fn any<T>(v: &[T], f: fn(T) -> bool) -> bool {
B
Brian Anderson 已提交
710
    for each(v) |elem| { if f(elem) { ret true; } }
711 712 713
    ret false;
}

714 715 716 717 718
/**
 * Return true if a predicate matches any elements in both vectors.
 *
 * If the vectors contains no elements then false is returned.
 */
719
pure fn any2<T, U>(v0: &[T], v1: &[U],
720
                   f: fn(T, U) -> bool) -> bool {
721 722
    let v0_len = len(v0);
    let v1_len = len(v1);
723
    let mut i = 0u;
724 725 726 727 728 729 730
    while i < v0_len && i < v1_len {
        if f(v0[i], v1[i]) { ret true; };
        i += 1u;
    }
    ret false;
}

731 732 733 734 735
/**
 * Return true if a predicate matches all elements
 *
 * If the vector contains no elements then true is returned.
 */
736
pure fn all<T>(v: &[T], f: fn(T) -> bool) -> bool {
B
Brian Anderson 已提交
737
    for each(v) |elem| { if !f(elem) { ret false; } }
738 739 740
    ret true;
}

741 742 743 744 745
/**
 * Return true if a predicate matches all elements
 *
 * If the vector contains no elements then true is returned.
 */
746
pure fn alli<T>(v: &[T], f: fn(uint, T) -> bool) -> bool {
B
Brian Anderson 已提交
747
    for eachi(v) |i, elem| { if !f(i, elem) { ret false; } }
748 749 750
    ret true;
}

751 752 753 754 755
/**
 * Return true if a predicate matches all elements in both vectors.
 *
 * If the vectors are not the same size then false is returned.
 */
756
pure fn all2<T, U>(v0: &[T], v1: &[U],
757
                   f: fn(T, U) -> bool) -> bool {
758 759
    let v0_len = len(v0);
    if v0_len != len(v1) { ret false; }
760
    let mut i = 0u;
761 762 763 764
    while i < v0_len { if !f(v0[i], v1[i]) { ret false; }; i += 1u; }
    ret true;
}

765
/// Return true if a vector contains an element with the given value
766
pure fn contains<T>(v: &[T], x: T) -> bool {
B
Brian Anderson 已提交
767
    for each(v) |elt| { if x == elt { ret true; } }
768 769 770
    ret false;
}

771
/// Returns the number of elements that are equal to a given value
772
pure fn count<T>(v: &[T], x: T) -> uint {
773
    let mut cnt = 0u;
B
Brian Anderson 已提交
774
    for each(v) |elt| { if x == elt { cnt += 1u; } }
775 776 777
    ret cnt;
}

778 779 780 781 782 783 784
/**
 * Search for the first element that matches a given predicate
 *
 * Apply function `f` to each element of `v`, starting from the first.
 * When function `f` returns true then an option containing the element
 * is returned. If `f` matches no elements then none is returned.
 */
785
pure fn find<T: copy>(v: &[T], f: fn(T) -> bool) -> option<T> {
786
    find_between(v, 0u, len(v), f)
787 788
}

789 790 791 792 793 794 795
/**
 * Search for the first element that matches a given predicate within a range
 *
 * Apply function `f` to each element of `v` within the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the element is returned. If `f` matches no elements then none is returned.
 */
796
pure fn find_between<T: copy>(v: &[T], start: uint, end: uint,
797
                      f: fn(T) -> bool) -> option<T> {
B
Brian Anderson 已提交
798
    option::map(position_between(v, start, end, f), |i| v[i])
799 800
}

801 802 803 804 805 806 807
/**
 * Search for the last element that matches a given predicate
 *
 * Apply function `f` to each element of `v` in reverse order. When function
 * `f` returns true then an option containing the element is returned. If `f`
 * matches no elements then none is returned.
 */
808
pure fn rfind<T: copy>(v: &[T], f: fn(T) -> bool) -> option<T> {
809
    rfind_between(v, 0u, len(v), f)
810 811
}

812 813 814 815 816 817 818
/**
 * Search for the last element that matches a given predicate within a range
 *
 * Apply function `f` to each element of `v` in reverse order within the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the element is returned. If `f` matches no elements then none is returned.
 */
819
pure fn rfind_between<T: copy>(v: &[T], start: uint, end: uint,
820
                               f: fn(T) -> bool) -> option<T> {
B
Brian Anderson 已提交
821
    option::map(rposition_between(v, start, end, f), |i| v[i])
822 823
}

824
/// Find the first index containing a matching value
825
pure fn position_elem<T>(v: &[T], x: T) -> option<uint> {
B
Brian Anderson 已提交
826
    position(v, |y| x == y)
827 828
}

829 830 831 832 833 834 835
/**
 * Find the first index matching some predicate
 *
 * Apply function `f` to each element of `v`.  When function `f` returns true
 * then an option containing the index is returned. If `f` matches no elements
 * then none is returned.
 */
836
pure fn position<T>(v: &[T], f: fn(T) -> bool) -> option<uint> {
837
    position_between(v, 0u, len(v), f)
838 839
}

840 841 842 843 844 845 846
/**
 * Find the first index matching some predicate within a range
 *
 * Apply function `f` to each element of `v` between the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the index is returned. If `f` matches no elements then none is returned.
 */
847
pure fn position_between<T>(v: &[T], start: uint, end: uint,
848
                            f: fn(T) -> bool) -> option<uint> {
849 850
    assert start <= end;
    assert end <= len(v);
851
    let mut i = start;
852
    while i < end { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
853 854 855
    ret none;
}

856
/// Find the last index containing a matching value
857
pure fn rposition_elem<T>(v: &[T], x: T) -> option<uint> {
B
Brian Anderson 已提交
858
    rposition(v, |y| x == y)
859 860
}

861 862 863 864 865 866 867
/**
 * Find the last index matching some predicate
 *
 * Apply function `f` to each element of `v` in reverse order.  When function
 * `f` returns true then an option containing the index is returned. If `f`
 * matches no elements then none is returned.
 */
868
pure fn rposition<T>(v: &[T], f: fn(T) -> bool) -> option<uint> {
869
    rposition_between(v, 0u, len(v), f)
870 871
}

872 873 874 875 876 877 878 879
/**
 * Find the last index matching some predicate within a range
 *
 * Apply function `f` to each element of `v` in reverse order between the
 * range [`start`, `end`). When function `f` returns true then an option
 * containing the index is returned. If `f` matches no elements then none is
 * returned.
 */
880
pure fn rposition_between<T>(v: &[T], start: uint, end: uint,
881
                             f: fn(T) -> bool) -> option<uint> {
882 883
    assert start <= end;
    assert end <= len(v);
884
    let mut i = end;
885 886 887 888
    while i > start {
        if f(v[i - 1u]) { ret some::<uint>(i - 1u); }
        i -= 1u;
    }
889 890 891 892 893 894 895
    ret none;
}

// FIXME: if issue #586 gets implemented, could have a postcondition
// saying the two result lists have the same length -- or, could
// return a nominal record with a constraint saying that, instead of
// returning a tuple (contingent on issue #869)
896 897 898 899 900 901 902 903
/**
 * Convert a vector of pairs into a pair of vectors
 *
 * Returns a tuple containing two vectors where the i-th element of the first
 * vector contains the first element of the i-th tuple of the input vector,
 * and the i-th element of the second vector contains the second element
 * of the i-th tuple of the input vector.
 */
904 905
pure fn unzip<T: copy, U: copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
    let mut as = ~[], bs = ~[];
B
Brian Anderson 已提交
906
    for each(v) |p| {
907 908 909 910 911 912
        let (a, b) = p;
        unchecked {
            vec::push(as, a);
            vec::push(bs, b);
        }
    }
913 914 915
    ret (as, bs);
}

916 917 918 919 920 921
/**
 * Convert two vectors to a vector of pairs
 *
 * Returns a vector of tuples, where the i-th tuple contains contains the
 * i-th elements from each of the input vectors.
 */
922 923
pure fn zip<T: copy, U: copy>(v: &[const T], u: &[const U]) -> ~[(T, U)] {
    let mut zipped = ~[];
924 925
    let sz = len(v);
    let mut i = 0u;
926
    assert sz == len(u);
927
    while i < sz unchecked { vec::push(zipped, (v[i], u[i])); i += 1u; }
928 929 930
    ret zipped;
}

931 932 933 934 935 936 937 938 939
/**
 * Swaps two elements in a vector
 *
 * # Arguments
 *
 * * v  The input vector
 * * a - The index of the first element
 * * b - The index of the second element
 */
940
fn swap<T>(&&v: ~[mut T], a: uint, b: uint) {
941 942 943
    v[a] <-> v[b];
}

944
/// Reverse the order of elements in a vector, in place
945
fn reverse<T>(v: ~[mut T]) {
946
    let mut i: uint = 0u;
947 948 949 950 951
    let ln = len::<T>(v);
    while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
}


952
/// Returns a vector with the order of elements reversed
953 954
pure fn reversed<T: copy>(v: &[const T]) -> ~[T] {
    let mut rs: ~[T] = ~[];
955
    let mut i = len::<T>(v);
956
    if i == 0u { ret rs; } else { i -= 1u; }
957 958 959 960
    unchecked {
        while i != 0u { vec::push(rs, v[i]); i -= 1u; }
        vec::push(rs, v[0]);
    }
961 962 963
    ret rs;
}

964 965 966 967 968 969
/**
 * Iterates over a slice
 *
 * Iterates over slice `v` and, for each element, calls function `f` with the
 * element's value.
 */
970
#[inline(always)]
971
pure fn iter<T>(v: &[T], f: fn(T)) {
972 973 974 975 976 977
    iter_between(v, 0u, vec::len(v), f)
}

/*
Function: iter_between

978
Iterates over a slice
979

980
Iterates over slice `v` and, for each element, calls function `f` with the
981 982 983 984
element's value.

*/
#[inline(always)]
985
pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
B
Brian Anderson 已提交
986
    do unpack_slice(v) |base_ptr, len| {
987 988 989 990 991 992 993 994 995 996
        assert start <= end;
        assert end <= len;
        unsafe {
            let mut n = end;
            let mut p = ptr::offset(base_ptr, start);
            while n > start {
                f(*p);
                p = ptr::offset(p, 1u);
                n -= 1u;
            }
997 998
        }
    }
999 1000
}

1001 1002 1003 1004 1005
/**
 * Iterates over a vector, with option to break
 *
 * Return true to continue, false to break.
 */
1006
#[inline(always)]
1007
pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
B
Brian Anderson 已提交
1008
    do vec::unpack_slice(v) |p, n| {
1009 1010 1011
        let mut n = n;
        let mut p = p;
        while n > 0u {
1012 1013 1014 1015
            unsafe {
                if !f(*p) { break; }
                p = ptr::offset(p, 1u);
            }
1016 1017
            n -= 1u;
        }
1018 1019 1020
    }
}

1021 1022 1023 1024 1025
/**
 * Iterates over a vector's elements and indices
 *
 * Return true to continue, false to break.
 */
1026
#[inline(always)]
1027
pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
B
Brian Anderson 已提交
1028
    do vec::unpack_slice(v) |p, n| {
1029 1030 1031
        let mut i = 0u;
        let mut p = p;
        while i < n {
1032 1033 1034 1035
            unsafe {
                if !f(i, *p) { break; }
                p = ptr::offset(p, 1u);
            }
1036 1037
            i += 1u;
        }
1038 1039 1040
    }
}

1041 1042 1043 1044 1045 1046 1047
/**
 * Iterates over two vectors simultaneously
 *
 * # Failure
 *
 * Both vectors must have the same length
 */
1048
#[inline]
1049
fn iter2<U, T>(v1: &[U], v2: &[T], f: fn(U, T)) {
1050
    assert len(v1) == len(v2);
B
Brian Anderson 已提交
1051
    for uint::range(0u, len(v1)) |i| {
1052 1053
        f(v1[i], v2[i])
    }
1054 1055
}

1056 1057 1058 1059 1060 1061
/**
 * Iterates over a vector's elements and indexes
 *
 * Iterates over vector `v` and, for each element, calls function `f` with the
 * element's value and index.
 */
1062
#[inline(always)]
1063
pure fn iteri<T>(v: &[T], f: fn(uint, T)) {
1064 1065
    let mut i = 0u;
    let l = len(v);
1066 1067 1068
    while i < l { f(i, v[i]); i += 1u; }
}

1069 1070 1071 1072 1073 1074
/**
 * Iterates over a vector in reverse
 *
 * Iterates over vector `v` and, for each element, calls function `f` with the
 * element's value.
 */
1075
pure fn riter<T>(v: &[T], f: fn(T)) {
B
Brian Anderson 已提交
1076
    riteri(v, |_i, v| f(v))
1077 1078
}

1079 1080 1081 1082 1083 1084
/**
 * Iterates over a vector's elements and indexes in reverse
 *
 * Iterates over vector `v` and, for each element, calls function `f` with the
 * element's value and index.
 */
1085
pure fn riteri<T>(v: &[T], f: fn(uint, T)) {
1086
    let mut i = len(v);
1087 1088 1089 1090 1091 1092
    while 0u < i {
        i -= 1u;
        f(i, v[i]);
    };
}

1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
/**
 * Iterate over all permutations of vector `v`.
 *
 * Permutations are produced in lexicographic order with respect to the order
 * of elements in `v` (so if `v` is sorted then the permutations are
 * lexicographically sorted).
 *
 * The total number of permutations produced is `len(v)!`.  If `v` contains
 * repeated elements, then some permutations are repeated.
 */
1103
pure fn permute<T: copy>(v: &[T], put: fn(~[T])) {
1104 1105
    let ln = len(v);
    if ln == 0u {
1106
        put(~[]);
1107 1108 1109 1110 1111 1112 1113
    } else {
        let mut i = 0u;
        while i < ln {
            let elt = v[i];
            let mut rest = slice(v, 0u, i);
            unchecked {
                push_all(rest, view(v, i+1u, ln));
B
Brian Anderson 已提交
1114
                permute(rest, |permutation| {
1115
                    put(append(~[elt], permutation))
1116
                })
1117 1118 1119
            }
            i += 1u;
        }
1120 1121 1122
    }
}

1123 1124
pure fn windowed<TT: copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
    let mut ww = ~[];
1125
    assert 1u <= nn;
B
Brian Anderson 已提交
1126
    vec::iteri (xx, |ii, _x| {
1127
        let len = vec::len(xx);
1128 1129
        if ii+nn <= len unchecked {
            vec::push(ww, vec::slice(xx, ii, ii+nn));
1130 1131 1132
        }
    });
    ret ww;
1133 1134
}

1135 1136 1137 1138 1139 1140
/**
 * Work with the buffer of a vector.
 *
 * Allows for unsafe manipulation of vector contents, which is useful for
 * foreign interop.
 */
1141
fn as_buf<E,T>(v: &[E], f: fn(*E) -> T) -> T {
B
Brian Anderson 已提交
1142
    unpack_slice(v, |buf, _len| f(buf))
1143 1144
}

1145
fn as_mut_buf<E,T>(v: &[mut E], f: fn(*mut E) -> T) -> T {
B
Brian Anderson 已提交
1146
    unpack_mut_slice(v, |buf, _len| f(buf))
1147 1148
}

1149
/// Work with the buffer and length of a slice.
1150
#[inline(always)]
1151
pure fn unpack_slice<T,U>(s: &[const T],
1152 1153 1154 1155 1156 1157
                          f: fn(*T, uint) -> U) -> U {
    unsafe {
        let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
1158 1159
}

1160
/// Work with the buffer and length of a slice.
1161
#[inline(always)]
1162
pure fn unpack_const_slice<T,U>(s: &[const T],
1163 1164 1165 1166 1167 1168 1169
                                f: fn(*const T, uint) -> U) -> U {
    unsafe {
        let v : *(*const T,uint) =
            ::unsafe::reinterpret_cast(ptr::addr_of(s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
1170 1171
}

1172
/// Work with the buffer and length of a slice.
1173
#[inline(always)]
1174
pure fn unpack_mut_slice<T,U>(s: &[mut T],
1175 1176 1177 1178 1179 1180 1181
                              f: fn(*mut T, uint) -> U) -> U {
    unsafe {
        let v : *(*const T,uint) =
            ::unsafe::reinterpret_cast(ptr::addr_of(s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
1182 1183
}

1184
impl extensions<T: copy> for ~[T] {
1185
    #[inline(always)]
1186
    pure fn +(rhs: &[const T]) -> ~[T] {
1187 1188 1189 1190
        append(self, rhs)
    }
}

1191
impl extensions<T: copy> for ~[mut T] {
1192
    #[inline(always)]
1193
    pure fn +(rhs: &[const T]) -> ~[mut T] {
1194 1195 1196 1197
        append_mut(self, rhs)
    }
}

1198
/// Extension methods for vectors
1199
impl extensions/&<T> for &[const T] {
1200
    /// Returns true if a vector contains no elements
1201
    #[inline]
1202
    pure fn is_empty() -> bool { is_empty(self) }
1203
    /// Returns true if a vector contains some elements
1204
    #[inline]
1205
    pure fn is_not_empty() -> bool { is_not_empty(self) }
1206
    /// Returns the length of a vector
1207 1208 1209 1210
    #[inline]
    pure fn len() -> uint { len(self) }
}

1211
/// Extension methods for vectors
1212
impl extensions/&<T: copy> for &[const T] {
1213
    /// Returns the first element of a vector
1214
    #[inline]
1215
    pure fn head() -> T { head(self) }
1216
    /// Returns all but the last elemnt of a vector
1217
    #[inline]
1218
    pure fn init() -> ~[T] { init(self) }
1219
    /// Returns the last element of a `v`, failing if the vector is empty.
1220
    #[inline]
1221
    pure fn last() -> T { last(self) }
1222
    /// Returns a copy of the elements from [`start`..`end`) from `v`.
1223
    #[inline]
1224
    pure fn slice(start: uint, end: uint) -> ~[T] { slice(self, start, end) }
1225
    /// Returns all but the first element of a vector
1226
    #[inline]
1227
    pure fn tail() -> ~[T] { tail(self) }
1228 1229
}

1230
/// Extension methods for vectors
1231
impl extensions/&<T> for &[T] {
1232
    /// Reduce a vector from right to left
1233
    #[inline]
1234
    pure fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) }
1235 1236 1237 1238 1239 1240
    /**
     * Iterates over a vector
     *
     * Iterates over vector `v` and, for each element, calls function `f` with
     * the element's value.
     */
1241
    #[inline]
1242
    pure fn iter(f: fn(T)) { iter(self, f) }
1243 1244 1245 1246 1247 1248
    /**
     * Iterates over a vector's elements and indexes
     *
     * Iterates over vector `v` and, for each element, calls function `f` with
     * the element's value and index.
     */
1249
    #[inline]
1250
    pure fn iteri(f: fn(uint, T)) { iteri(self, f) }
1251 1252 1253 1254 1255 1256 1257
    /**
     * Find the first index matching some predicate
     *
     * Apply function `f` to each element of `v`.  When function `f` returns
     * true then an option containing the index is returned. If `f` matches no
     * elements then none is returned.
     */
1258
    #[inline]
1259
    pure fn position(f: fn(T) -> bool) -> option<uint> { position(self, f) }
1260
    /// Find the first index containing a matching value
1261
    #[inline]
1262
    pure fn position_elem(x: T) -> option<uint> { position_elem(self, x) }
1263 1264 1265 1266 1267 1268
    /**
     * Iterates over a vector in reverse
     *
     * Iterates over vector `v` and, for each element, calls function `f` with
     * the element's value.
     */
1269
    #[inline]
1270
    pure fn riter(f: fn(T)) { riter(self, f) }
1271 1272 1273 1274 1275 1276
    /**
     * Iterates over a vector's elements and indexes in reverse
     *
     * Iterates over vector `v` and, for each element, calls function `f` with
     * the element's value and index.
     */
1277
    #[inline]
1278
    pure fn riteri(f: fn(uint, T)) { riteri(self, f) }
1279 1280 1281 1282 1283 1284 1285
    /**
     * Find the last index matching some predicate
     *
     * Apply function `f` to each element of `v` in reverse order.  When
     * function `f` returns true then an option containing the index is
     * returned. If `f` matches no elements then none is returned.
     */
1286
    #[inline]
1287
    pure fn rposition(f: fn(T) -> bool) -> option<uint> { rposition(self, f) }
1288
    /// Find the last index containing a matching value
1289
    #[inline]
1290
    pure fn rposition_elem(x: T) -> option<uint> { rposition_elem(self, x) }
1291
    /// Apply a function to each element of a vector and return the results
1292
    #[inline]
1293
    pure fn map<U>(f: fn(T) -> U) -> ~[U] { map(self, f) }
1294 1295 1296 1297
    /**
     * Apply a function to the index and value of each element in the vector
     * and return the results
     */
1298
    pure fn mapi<U>(f: fn(uint, T) -> U) -> ~[U] {
1299
        mapi(self, f)
N
Niko Matsakis 已提交
1300
    }
E
Eric Holk 已提交
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312

    #[inline]
    fn map_r<U>(f: fn(x: &self.T) -> U) -> ~[U] {
        let mut r = ~[];
        let mut i = 0;
        while i < self.len() {
            push(r, f(&self[i]));
            i += 1;
        }
        r
    }

1313 1314 1315 1316 1317
    /**
     * Returns true if the function returns true for all elements.
     *
     *     If the vector is empty, true is returned.
     */
1318
    pure fn alli(f: fn(uint, T) -> bool) -> bool {
1319 1320
        alli(self, f)
    }
1321 1322 1323 1324
    /**
     * Apply a function to each element of a vector and return a concatenation
     * of each result vector
     */
1325
    #[inline]
1326
    pure fn flat_map<U>(f: fn(T) -> ~[U]) -> ~[U] { flat_map(self, f) }
1327 1328 1329 1330 1331 1332
    /**
     * Apply a function to each element of a vector and return the results
     *
     * If function `f` returns `none` then that element is excluded from
     * the resulting vector.
     */
1333
    #[inline]
1334
    pure fn filter_map<U: copy>(f: fn(T) -> option<U>) -> ~[U] {
1335 1336
        filter_map(self, f)
    }
1337
}
1338

1339
/// Extension methods for vectors
1340
impl extensions/&<T: copy> for &[T] {
1341 1342 1343 1344 1345 1346 1347
    /**
     * Construct a new vector from the elements of a vector for which some
     * predicate holds.
     *
     * Apply function `f` to each element of `v` and return a vector
     * containing only those elements for which `f` returned true.
     */
1348
    #[inline]
1349
    pure fn filter(f: fn(T) -> bool) -> ~[T] { filter(self, f) }
1350 1351 1352 1353 1354 1355 1356
    /**
     * Search for the first element that matches a given predicate
     *
     * Apply function `f` to each element of `v`, starting from the first.
     * When function `f` returns true then an option containing the element
     * is returned. If `f` matches no elements then none is returned.
     */
1357
    #[inline]
1358
    pure fn find(f: fn(T) -> bool) -> option<T> { find(self, f) }
1359 1360 1361 1362 1363 1364 1365
    /**
     * Search for the last element that matches a given predicate
     *
     * Apply function `f` to each element of `v` in reverse order. When
     * function `f` returns true then an option containing the element is
     * returned. If `f` matches no elements then none is returned.
     */
1366
    #[inline]
1367
    pure fn rfind(f: fn(T) -> bool) -> option<T> { rfind(self, f) }
1368 1369
}

1370
/// Unsafe operations
1371
mod unsafe {
T
Tim Chevalier 已提交
1372
    // FIXME: This should have crate visibility (#1893 blocks that)
1373
    /// The internal representation of a vector
1374 1375 1376 1377 1378 1379
    type vec_repr = {
        box_header: (uint, uint, uint, uint),
        mut fill: uint,
        mut alloc: uint,
        data: u8
    };
1380

1381 1382 1383 1384 1385 1386 1387 1388
    /**
     * Constructs a vector from an unsafe pointer to a buffer
     *
     * # Arguments
     *
     * * ptr - An unsafe pointer to a buffer of `T`
     * * elts - The number of elements in the buffer
     */
1389
    #[inline(always)]
1390
    unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
1391 1392 1393
        ret ::unsafe::reinterpret_cast(
            rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
                                        ptr as *(),
1394
                                        elts as size_t));
1395 1396
    }

1397 1398 1399 1400 1401 1402 1403
    /**
     * Sets the length of a vector
     *
     * This will explicitly set the size of the vector, without actually
     * modifing its buffers, so it is up to the caller to ensure that
     * the vector is actually the specified size.
     */
1404
    #[inline(always)]
1405
    unsafe fn set_len<T>(&&v: ~[const T], new_len: uint) {
1406 1407 1408 1409
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        (**repr).fill = new_len * sys::size_of::<T>();
    }

1410 1411 1412 1413 1414 1415 1416 1417 1418
    /**
     * Returns an unsafe pointer to the vector's buffer
     *
     * The caller must ensure that the vector outlives the pointer this
     * function returns, or else it will end up pointing to garbage.
     *
     * Modifying the vector may cause its buffer to be reallocated, which
     * would also make any pointers to it invalid.
     */
1419
    #[inline(always)]
1420
    unsafe fn to_ptr<T>(v: ~[const T]) -> *T {
1421 1422 1423
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
    }
1424 1425


1426 1427 1428 1429
    /**
     * Form a slice from a pointer and length (as a number of units,
     * not bytes).
     */
1430
    #[inline(always)]
1431
    unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn(&& &[T]) -> U) -> U {
1432
        let pair = (p, len * sys::size_of::<T>());
1433
        let v : *(&blk.[T]) =
1434
            ::unsafe::reinterpret_cast(ptr::addr_of(pair));
1435 1436
        f(*v)
    }
1437 1438
}

1439
/// Operations on `[u8]`
1440 1441 1442 1443 1444
mod u8 {
    export cmp;
    export lt, le, eq, ne, ge, gt;
    export hash;

1445
    /// Bytewise string comparison
1446
    pure fn cmp(&&a: ~[u8], &&b: ~[u8]) -> int {
1447 1448
        let a_len = len(a);
        let b_len = len(b);
1449
        let n = uint::min(a_len, b_len) as libc::size_t;
1450 1451 1452 1453
        let r = unsafe {
            libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
                         unsafe::to_ptr(b) as *libc::c_void, n) as int
        };
1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465

        if r != 0 { r } else {
            if a_len == b_len {
                0
            } else if a_len < b_len {
                -1
            } else {
                1
            }
        }
    }

1466
    /// Bytewise less than or equal
1467
    pure fn lt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) < 0 }
1468

1469
    /// Bytewise less than or equal
1470
    pure fn le(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) <= 0 }
1471

1472
    /// Bytewise equality
1473
    pure fn eq(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) == 0 } }
1474

1475
    /// Bytewise inequality
1476
    pure fn ne(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) != 0 } }
1477

1478
    /// Bytewise greater than or equal
1479
    pure fn ge(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) >= 0 }
1480

1481
    /// Bytewise greater than
1482
    pure fn gt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) > 0 }
1483

1484
    /// String hash function
1485
    fn hash(&&s: ~[u8]) -> uint {
T
Tim Chevalier 已提交
1486 1487 1488
        /* Seems to have been tragically copy/pasted from str.rs,
           or vice versa. But I couldn't figure out how to abstract
           it out. -- tjc */
1489

1490
        let mut u: uint = 5381u;
B
Brian Anderson 已提交
1491
        vec::iter(s, |c| {u *= 33u; u += c as uint;});
1492 1493 1494 1495
        ret u;
    }
}

1496 1497 1498 1499 1500
// ___________________________________________________________________________
// ITERATION TRAIT METHODS
//
// This cannot be used with iter-trait.rs because of the region pointer
// required in the slice.
1501
impl extensions/&<A> of iter::base_iter<A> for &[const A] {
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
    fn each(blk: fn(A) -> bool) { each(self, blk) }
    fn size_hint() -> option<uint> { some(len(self)) }
    fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
    fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
    fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
    fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
        iter::foldl(self, b0, blk)
    }
    fn contains(x: A) -> bool { iter::contains(self, x) }
    fn count(x: A) -> uint { iter::count(self, x) }
}
1513 1514
impl extensions/&<A:copy> for &[const A] {
    fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
1515 1516
        iter::filter_to_vec(self, pred)
    }
1517 1518
    fn map_to_vec<B>(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
    fn to_vec() -> ~[A] { iter::to_vec(self) }
1519

T
Tim Chevalier 已提交
1520
    // FIXME--bug in resolve prevents this from working (#2611)
1521
    // fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> ~[B] {
1522 1523 1524 1525 1526 1527 1528 1529
    //     iter::flat_map_to_vec(self, op)
    // }

    fn min() -> A { iter::min(self) }
    fn max() -> A { iter::max(self) }
}
// ___________________________________________________________________________

1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542
#[cfg(test)]
mod tests {

    fn square(n: uint) -> uint { ret n * n; }

    fn square_ref(&&n: uint) -> uint { ret n * n; }

    pure fn is_three(&&n: uint) -> bool { ret n == 3u; }

    pure fn is_odd(&&n: uint) -> bool { ret n % 2u == 1u; }

    pure fn is_equal(&&x: uint, &&y:uint) -> bool { ret x == y; }

1543
    fn square_if_odd(&&n: uint) -> option<uint> {
1544 1545 1546 1547 1548 1549
        ret if n % 2u == 1u { some(n * n) } else { none };
    }

    fn add(&&x: uint, &&y: uint) -> uint { ret x + y; }

    #[test]
1550 1551 1552
    fn test_unsafe_ptrs() {
        unsafe {
            // Test on-stack copy-from-buf.
1553
            let a = ~[1, 2, 3];
1554 1555 1556 1557 1558 1559 1560 1561
            let mut ptr = unsafe::to_ptr(a);
            let b = unsafe::from_buf(ptr, 3u);
            assert (len(b) == 3u);
            assert (b[0] == 1);
            assert (b[1] == 2);
            assert (b[2] == 3);

            // Test on-heap copy-from-buf.
1562
            let c = ~[1, 2, 3, 4, 5];
1563 1564 1565 1566 1567 1568 1569 1570 1571
            ptr = unsafe::to_ptr(c);
            let d = unsafe::from_buf(ptr, 5u);
            assert (len(d) == 5u);
            assert (d[0] == 1);
            assert (d[1] == 2);
            assert (d[2] == 3);
            assert (d[3] == 4);
            assert (d[4] == 5);
        }
1572 1573 1574
    }

    #[test]
1575 1576
    fn test_from_fn() {
        // Test on-stack from_fn.
1577
        let mut v = from_fn(3u, square);
1578 1579 1580 1581 1582
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);

1583 1584
        // Test on-heap from_fn.
        v = from_fn(5u, square);
1585 1586 1587 1588 1589 1590 1591 1592 1593
        assert (len(v) == 5u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);
        assert (v[3] == 9u);
        assert (v[4] == 16u);
    }

    #[test]
1594 1595
    fn test_from_elem() {
        // Test on-stack from_elem.
1596
        let mut v = from_elem(2u, 10u);
1597 1598 1599 1600
        assert (len(v) == 2u);
        assert (v[0] == 10u);
        assert (v[1] == 10u);

1601 1602
        // Test on-heap from_elem.
        v = from_elem(6u, 20u);
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
        assert (v[0] == 20u);
        assert (v[1] == 20u);
        assert (v[2] == 20u);
        assert (v[3] == 20u);
        assert (v[4] == 20u);
        assert (v[5] == 20u);
    }

    #[test]
    fn test_is_empty() {
1613 1614
        assert (is_empty::<int>(~[]));
        assert (!is_empty(~[0]));
1615 1616 1617 1618
    }

    #[test]
    fn test_is_not_empty() {
1619 1620
        assert (is_not_empty(~[0]));
        assert (!is_not_empty::<int>(~[]));
1621 1622 1623 1624
    }

    #[test]
    fn test_head() {
1625
        let a = ~[11, 12];
1626 1627 1628 1629 1630
        assert (head(a) == 11);
    }

    #[test]
    fn test_tail() {
1631 1632
        let mut a = ~[11];
        assert (tail(a) == ~[]);
1633

1634 1635
        a = ~[11, 12];
        assert (tail(a) == ~[12]);
1636 1637 1638 1639
    }

    #[test]
    fn test_last() {
1640
        let mut n = last_opt(~[]);
1641
        assert (n == none);
1642
        n = last_opt(~[1, 2, 3]);
1643
        assert (n == some(3));
1644
        n = last_opt(~[1, 2, 3, 4, 5]);
1645 1646 1647 1648 1649 1650
        assert (n == some(5));
    }

    #[test]
    fn test_slice() {
        // Test on-stack -> on-stack slice.
1651
        let mut v = slice(~[1, 2, 3], 1u, 3u);
1652 1653 1654 1655 1656
        assert (len(v) == 2u);
        assert (v[0] == 2);
        assert (v[1] == 3);

        // Test on-heap -> on-stack slice.
1657
        v = slice(~[1, 2, 3, 4, 5], 0u, 3u);
1658 1659 1660 1661 1662 1663
        assert (len(v) == 3u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);

        // Test on-heap -> on-heap slice.
1664
        v = slice(~[1, 2, 3, 4, 5, 6], 1u, 6u);
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675
        assert (len(v) == 5u);
        assert (v[0] == 2);
        assert (v[1] == 3);
        assert (v[2] == 4);
        assert (v[3] == 5);
        assert (v[4] == 6);
    }

    #[test]
    fn test_pop() {
        // Test on-stack pop.
1676
        let mut v = ~[1, 2, 3];
1677
        let mut e = pop(v);
1678 1679 1680 1681 1682 1683
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (e == 3);

        // Test on-heap pop.
1684
        v = ~[1, 2, 3, 4, 5];
1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
        e = pop(v);
        assert (len(v) == 4u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);
        assert (v[3] == 4);
        assert (e == 5);
    }

    #[test]
    fn test_push() {
        // Test on-stack push().
1697
        let mut v = ~[];
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
        push(v, 1);
        assert (len(v) == 1u);
        assert (v[0] == 1);

        // Test on-heap push().
        push(v, 2);
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
    }

    #[test]
    fn test_grow() {
        // Test on-stack grow().
1712
        let mut v = ~[];
1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729
        grow(v, 2u, 1);
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 1);

        // Test on-heap grow().
        grow(v, 3u, 2);
        assert (len(v) == 5u);
        assert (v[0] == 1);
        assert (v[1] == 1);
        assert (v[2] == 2);
        assert (v[3] == 2);
        assert (v[4] == 2);
    }

    #[test]
    fn test_grow_fn() {
1730
        let mut v = ~[];
1731 1732 1733 1734 1735 1736 1737 1738 1739
        grow_fn(v, 3u, square);
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);
    }

    #[test]
    fn test_grow_set() {
1740
        let mut v = ~[mut 1, 2, 3];
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
        grow_set(v, 4u, 4, 5);
        assert (len(v) == 5u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);
        assert (v[3] == 4);
        assert (v[4] == 5);
    }

    #[test]
    fn test_map() {
        // Test on-stack map.
1753
        let mut v = ~[1u, 2u, 3u];
1754
        let mut w = map(v, square_ref);
1755 1756 1757 1758 1759 1760
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);

        // Test on-heap map.
1761
        v = ~[1u, 2u, 3u, 4u, 5u];
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
        w = map(v, square_ref);
        assert (len(w) == 5u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);
        assert (w[3] == 16u);
        assert (w[4] == 25u);
    }

    #[test]
    fn test_map2() {
        fn times(&&x: int, &&y: int) -> int { ret x * y; }
        let f = times;
1775 1776
        let v0 = ~[1, 2, 3, 4, 5];
        let v1 = ~[5, 4, 3, 2, 1];
1777
        let u = map2::<int, int, int>(v0, v1, f);
1778
        let mut i = 0;
1779 1780 1781 1782 1783 1784
        while i < 5 { assert (v0[i] * v1[i] == u[i]); i += 1; }
    }

    #[test]
    fn test_filter_map() {
        // Test on-stack filter-map.
1785
        let mut v = ~[1u, 2u, 3u];
1786
        let mut w = filter_map(v, square_if_odd);
1787 1788 1789 1790 1791
        assert (len(w) == 2u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);

        // Test on-heap filter-map.
1792
        v = ~[1u, 2u, 3u, 4u, 5u];
1793 1794 1795 1796 1797 1798
        w = filter_map(v, square_if_odd);
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);
        assert (w[2] == 25u);

1799
        fn halve(&&i: int) -> option<int> {
1800 1801 1802 1803 1804
            if i % 2 == 0 {
                ret option::some::<int>(i / 2);
            } else { ret option::none::<int>; }
        }
        fn halve_for_sure(&&i: int) -> int { ret i / 2; }
1805 1806 1807 1808 1809
        let all_even: ~[int] = ~[0, 2, 8, 6];
        let all_odd1: ~[int] = ~[1, 7, 3];
        let all_odd2: ~[int] = ~[];
        let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3];
        let mix_dest: ~[int] = ~[1, 3, 0, 0];
1810
        assert (filter_map(all_even, halve) == map(all_even, halve_for_sure));
1811 1812
        assert (filter_map(all_odd1, halve) == ~[]);
        assert (filter_map(all_odd2, halve) == ~[]);
1813 1814 1815 1816 1817
        assert (filter_map(mix, halve) == mix_dest);
    }

    #[test]
    fn test_filter() {
1818 1819
        assert filter(~[1u, 2u, 3u], is_odd) == ~[1u, 3u];
        assert filter(~[1u, 2u, 4u, 8u, 16u], is_three) == ~[];
1820 1821 1822 1823 1824
    }

    #[test]
    fn test_foldl() {
        // Test on-stack fold.
1825
        let mut v = ~[1u, 2u, 3u];
1826
        let mut sum = foldl(0u, v, add);
1827 1828 1829
        assert (sum == 6u);

        // Test on-heap fold.
1830
        v = ~[1u, 2u, 3u, 4u, 5u];
1831 1832 1833 1834 1835 1836 1837 1838 1839
        sum = foldl(0u, v, add);
        assert (sum == 15u);
    }

    #[test]
    fn test_foldl2() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1840
        let mut v = ~[1, 2, 3, 4];
1841 1842 1843 1844 1845 1846 1847 1848 1849
        let sum = foldl(0, v, sub);
        assert sum == -10;
    }

    #[test]
    fn test_foldr() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1850
        let mut v = ~[1, 2, 3, 4];
1851 1852 1853 1854 1855 1856
        let sum = foldr(v, 0, sub);
        assert sum == -2;
    }

    #[test]
    fn test_iter_empty() {
1857
        let mut i = 0;
B
Brian Anderson 已提交
1858
        iter::<int>(~[], |_v| i += 1);
1859 1860 1861 1862 1863
        assert i == 0;
    }

    #[test]
    fn test_iter_nonempty() {
1864
        let mut i = 0;
B
Brian Anderson 已提交
1865
        iter(~[1, 2, 3], |v| i += v);
1866 1867 1868 1869 1870
        assert i == 6;
    }

    #[test]
    fn test_iteri() {
1871
        let mut i = 0;
B
Brian Anderson 已提交
1872
        iteri(~[1, 2, 3], |j, v| {
1873 1874 1875 1876 1877 1878 1879 1880 1881
            if i == 0 { assert v == 1; }
            assert j + 1u == v as uint;
            i += v;
        });
        assert i == 6;
    }

    #[test]
    fn test_riter_empty() {
1882
        let mut i = 0;
B
Brian Anderson 已提交
1883
        riter::<int>(~[], |_v| i += 1);
1884 1885 1886 1887 1888
        assert i == 0;
    }

    #[test]
    fn test_riter_nonempty() {
1889
        let mut i = 0;
B
Brian Anderson 已提交
1890
        riter(~[1, 2, 3], |v| {
1891 1892 1893 1894 1895 1896 1897 1898
            if i == 0 { assert v == 3; }
            i += v
        });
        assert i == 6;
    }

    #[test]
    fn test_riteri() {
1899
        let mut i = 0;
B
Brian Anderson 已提交
1900
        riteri(~[0, 1, 2], |j, v| {
1901 1902 1903 1904 1905 1906 1907 1908 1909
            if i == 0 { assert v == 2; }
            assert j == v as uint;
            i += v;
        });
        assert i == 3;
    }

    #[test]
    fn test_permute() {
1910
        let mut results: ~[~[int]];
1911

1912
        results = ~[];
B
Brian Anderson 已提交
1913
        permute(~[], |v| vec::push(results, v));
1914
        assert results == ~[~[]];
1915

1916
        results = ~[];
B
Brian Anderson 已提交
1917
        permute(~[7], |v| results += ~[v]);
1918
        assert results == ~[~[7]];
1919

1920
        results = ~[];
B
Brian Anderson 已提交
1921
        permute(~[1,1], |v| results += ~[v]);
1922
        assert results == ~[~[1,1],~[1,1]];
1923

1924
        results = ~[];
B
Brian Anderson 已提交
1925
        permute(~[5,2,0], |v| results += ~[v]);
1926
        assert results ==
1927
            ~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]];
1928 1929 1930 1931
    }

    #[test]
    fn test_any_and_all() {
1932 1933 1934 1935
        assert (any(~[1u, 2u, 3u], is_three));
        assert (!any(~[0u, 1u, 2u], is_three));
        assert (any(~[1u, 2u, 3u, 4u, 5u], is_three));
        assert (!any(~[1u, 2u, 4u, 5u, 6u], is_three));
1936

1937 1938 1939 1940
        assert (all(~[3u, 3u, 3u], is_three));
        assert (!all(~[3u, 3u, 2u], is_three));
        assert (all(~[3u, 3u, 3u, 3u, 3u], is_three));
        assert (!all(~[3u, 3u, 0u, 1u, 2u], is_three));
1941 1942 1943 1944 1945
    }

    #[test]
    fn test_any2_and_all2() {

1946 1947 1948 1949
        assert (any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal));
        assert (any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal));
        assert (!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal));
        assert (any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal));
1950

1951 1952 1953 1954
        assert (all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal));
        assert (!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal));
        assert (!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal));
        assert (!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal));
1955 1956 1957 1958
    }

    #[test]
    fn test_zip_unzip() {
1959 1960
        let v1 = ~[1, 2, 3];
        let v2 = ~[4, 5, 6];
1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975

        let z1 = zip(v1, v2);

        assert ((1, 4) == z1[0]);
        assert ((2, 5) == z1[1]);
        assert ((3, 6) == z1[2]);

        let (left, right) = unzip(z1);

        assert ((1, 4) == (left[0], right[0]));
        assert ((2, 5) == (left[1], right[1]));
        assert ((3, 6) == (left[2], right[2]));
    }

    #[test]
1976
    fn test_position_elem() {
1977
        assert position_elem(~[], 1) == none;
1978

1979
        let v1 = ~[1, 2, 3, 3, 2, 5];
1980 1981 1982 1983
        assert position_elem(v1, 1) == some(0u);
        assert position_elem(v1, 2) == some(1u);
        assert position_elem(v1, 5) == some(5u);
        assert position_elem(v1, 4) == none;
1984 1985 1986
    }

    #[test]
1987
    fn test_position() {
1988 1989
        fn less_than_three(&&i: int) -> bool { ret i < 3; }
        fn is_eighteen(&&i: int) -> bool { ret i == 18; }
1990

1991
        assert position(~[], less_than_three) == none;
1992

1993
        let v1 = ~[5, 4, 3, 2, 1];
1994 1995
        assert position(v1, less_than_three) == some(3u);
        assert position(v1, is_eighteen) == none;
1996 1997 1998
    }

    #[test]
1999
    fn test_position_between() {
2000
        assert position_between(~[], 0u, 0u, f) == none;
2001 2002

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
2003
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2004

2005 2006 2007 2008 2009
        assert position_between(v, 0u, 0u, f) == none;
        assert position_between(v, 0u, 1u, f) == none;
        assert position_between(v, 0u, 2u, f) == some(1u);
        assert position_between(v, 0u, 3u, f) == some(1u);
        assert position_between(v, 0u, 4u, f) == some(1u);
2010

2011 2012 2013 2014
        assert position_between(v, 1u, 1u, f) == none;
        assert position_between(v, 1u, 2u, f) == some(1u);
        assert position_between(v, 1u, 3u, f) == some(1u);
        assert position_between(v, 1u, 4u, f) == some(1u);
2015

2016 2017 2018
        assert position_between(v, 2u, 2u, f) == none;
        assert position_between(v, 2u, 3u, f) == none;
        assert position_between(v, 2u, 4u, f) == some(3u);
2019

2020 2021
        assert position_between(v, 3u, 3u, f) == none;
        assert position_between(v, 3u, 4u, f) == some(3u);
2022

2023
        assert position_between(v, 4u, 4u, f) == none;
2024 2025
    }

2026 2027
    #[test]
    fn test_find() {
2028
        assert find(~[], f) == none;
2029 2030 2031

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2032
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2033 2034 2035 2036 2037 2038

        assert find(v, f) == some((1, 'b'));
        assert find(v, g) == none;
    }

    #[test]
2039
    fn test_find_between() {
2040
        assert find_between(~[], 0u, 0u, f) == none;
2041 2042

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
2043
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2044

2045 2046 2047 2048 2049
        assert find_between(v, 0u, 0u, f) == none;
        assert find_between(v, 0u, 1u, f) == none;
        assert find_between(v, 0u, 2u, f) == some((1, 'b'));
        assert find_between(v, 0u, 3u, f) == some((1, 'b'));
        assert find_between(v, 0u, 4u, f) == some((1, 'b'));
2050

2051 2052 2053 2054
        assert find_between(v, 1u, 1u, f) == none;
        assert find_between(v, 1u, 2u, f) == some((1, 'b'));
        assert find_between(v, 1u, 3u, f) == some((1, 'b'));
        assert find_between(v, 1u, 4u, f) == some((1, 'b'));
2055

2056 2057 2058
        assert find_between(v, 2u, 2u, f) == none;
        assert find_between(v, 2u, 3u, f) == none;
        assert find_between(v, 2u, 4u, f) == some((3, 'b'));
2059

2060 2061
        assert find_between(v, 3u, 3u, f) == none;
        assert find_between(v, 3u, 4u, f) == some((3, 'b'));
2062

2063
        assert find_between(v, 4u, 4u, f) == none;
2064 2065
    }

2066 2067
    #[test]
    fn test_rposition() {
2068
        assert find(~[], f) == none;
2069 2070 2071

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2072
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2073 2074 2075 2076 2077 2078

        assert position(v, f) == some(1u);
        assert position(v, g) == none;
    }

    #[test]
2079
    fn test_rposition_between() {
2080
        assert rposition_between(~[], 0u, 0u, f) == none;
2081 2082

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
2083
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2084

2085 2086 2087 2088 2089
        assert rposition_between(v, 0u, 0u, f) == none;
        assert rposition_between(v, 0u, 1u, f) == none;
        assert rposition_between(v, 0u, 2u, f) == some(1u);
        assert rposition_between(v, 0u, 3u, f) == some(1u);
        assert rposition_between(v, 0u, 4u, f) == some(3u);
2090

2091 2092 2093 2094
        assert rposition_between(v, 1u, 1u, f) == none;
        assert rposition_between(v, 1u, 2u, f) == some(1u);
        assert rposition_between(v, 1u, 3u, f) == some(1u);
        assert rposition_between(v, 1u, 4u, f) == some(3u);
2095

2096 2097 2098
        assert rposition_between(v, 2u, 2u, f) == none;
        assert rposition_between(v, 2u, 3u, f) == none;
        assert rposition_between(v, 2u, 4u, f) == some(3u);
2099

2100 2101
        assert rposition_between(v, 3u, 3u, f) == none;
        assert rposition_between(v, 3u, 4u, f) == some(3u);
2102

2103
        assert rposition_between(v, 4u, 4u, f) == none;
2104
    }
2105 2106 2107

    #[test]
    fn test_rfind() {
2108
        assert rfind(~[], f) == none;
2109 2110 2111

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2112
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2113 2114 2115 2116 2117 2118

        assert rfind(v, f) == some((3, 'b'));
        assert rfind(v, g) == none;
    }

    #[test]
2119
    fn test_rfind_between() {
2120
        assert rfind_between(~[], 0u, 0u, f) == none;
2121 2122

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
2123
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2124

2125 2126 2127 2128 2129
        assert rfind_between(v, 0u, 0u, f) == none;
        assert rfind_between(v, 0u, 1u, f) == none;
        assert rfind_between(v, 0u, 2u, f) == some((1, 'b'));
        assert rfind_between(v, 0u, 3u, f) == some((1, 'b'));
        assert rfind_between(v, 0u, 4u, f) == some((3, 'b'));
2130

2131 2132 2133 2134
        assert rfind_between(v, 1u, 1u, f) == none;
        assert rfind_between(v, 1u, 2u, f) == some((1, 'b'));
        assert rfind_between(v, 1u, 3u, f) == some((1, 'b'));
        assert rfind_between(v, 1u, 4u, f) == some((3, 'b'));
2135

2136 2137 2138
        assert rfind_between(v, 2u, 2u, f) == none;
        assert rfind_between(v, 2u, 3u, f) == none;
        assert rfind_between(v, 2u, 4u, f) == some((3, 'b'));
2139

2140 2141
        assert rfind_between(v, 3u, 3u, f) == none;
        assert rfind_between(v, 3u, 4u, f) == some((3, 'b'));
2142

2143
        assert rfind_between(v, 4u, 4u, f) == none;
2144 2145 2146 2147
    }

    #[test]
    fn reverse_and_reversed() {
2148
        let v: ~[mut int] = ~[mut 10, 20];
2149 2150 2151 2152 2153
        assert (v[0] == 10);
        assert (v[1] == 20);
        reverse(v);
        assert (v[0] == 20);
        assert (v[1] == 10);
2154
        let v2 = reversed::<int>(~[10, 20]);
2155 2156 2157 2158 2159 2160
        assert (v2[0] == 20);
        assert (v2[1] == 10);
        v[0] = 30;
        assert (v2[0] == 20);
        // Make sure they work with 0-length vectors too.

2161 2162 2163
        let v4 = reversed::<int>(~[]);
        assert (v4 == ~[]);
        let v3: ~[mut int] = ~[mut];
2164 2165 2166 2167 2168
        reverse::<int>(v3);
    }

    #[test]
    fn reversed_mut() {
2169
        let v2 = reversed::<int>(~[mut 10, 20]);
2170 2171 2172 2173 2174 2175
        assert (v2[0] == 20);
        assert (v2[1] == 10);
    }

    #[test]
    fn test_init() {
2176 2177
        let v = init(~[1, 2, 3]);
        assert v == ~[1, 2];
2178 2179
    }

2180 2181 2182 2183
    #[test]
    fn test_split() {
        fn f(&&x: int) -> bool { x == 3 }

2184 2185 2186 2187 2188
        assert split(~[], f) == ~[];
        assert split(~[1, 2], f) == ~[~[1, 2]];
        assert split(~[3, 1, 2], f) == ~[~[], ~[1, 2]];
        assert split(~[1, 2, 3], f) == ~[~[1, 2], ~[]];
        assert split(~[1, 2, 3, 4, 3, 5], f) == ~[~[1, 2], ~[4], ~[5]];
2189 2190 2191 2192 2193 2194
    }

    #[test]
    fn test_splitn() {
        fn f(&&x: int) -> bool { x == 3 }

2195 2196 2197 2198 2199 2200
        assert splitn(~[], 1u, f) == ~[];
        assert splitn(~[1, 2], 1u, f) == ~[~[1, 2]];
        assert splitn(~[3, 1, 2], 1u, f) == ~[~[], ~[1, 2]];
        assert splitn(~[1, 2, 3], 1u, f) == ~[~[1, 2], ~[]];
        assert splitn(~[1, 2, 3, 4, 3, 5], 1u, f) ==
                      ~[~[1, 2], ~[4, 3, 5]];
2201 2202 2203 2204 2205 2206
    }

    #[test]
    fn test_rsplit() {
        fn f(&&x: int) -> bool { x == 3 }

2207 2208 2209 2210
        assert rsplit(~[], f) == ~[];
        assert rsplit(~[1, 2], f) == ~[~[1, 2]];
        assert rsplit(~[1, 2, 3], f) == ~[~[1, 2], ~[]];
        assert rsplit(~[1, 2, 3, 4, 3, 5], f) == ~[~[1, 2], ~[4], ~[5]];
2211 2212 2213 2214 2215 2216
    }

    #[test]
    fn test_rsplitn() {
        fn f(&&x: int) -> bool { x == 3 }

2217 2218 2219 2220 2221
        assert rsplitn(~[], 1u, f) == ~[];
        assert rsplitn(~[1, 2], 1u, f) == ~[~[1, 2]];
        assert rsplitn(~[1, 2, 3], 1u, f) == ~[~[1, 2], ~[]];
        assert rsplitn(~[1, 2, 3, 4, 3, 5], 1u, f) ==
                       ~[~[1, 2, 3, 4], ~[5]];
2222 2223
    }

2224
    #[test]
B
Brian Anderson 已提交
2225
    #[should_fail]
2226
    #[ignore(cfg(windows))]
2227
    fn test_init_empty() {
2228
        init::<int>(~[]);
2229 2230 2231 2232
    }

    #[test]
    fn test_concat() {
2233
        assert concat(~[~[1], ~[2,3]]) == ~[1, 2, 3];
2234 2235
    }

2236 2237
    #[test]
    fn test_connect() {
2238 2239 2240
        assert connect(~[], 0) == ~[];
        assert connect(~[~[1], ~[2, 3]], 0) == ~[1, 0, 2, 3];
        assert connect(~[~[1], ~[2], ~[3]], 0) == ~[1, 0, 2, 0, 3];
2241 2242
    }

2243 2244
    #[test]
    fn test_windowed () {
2245 2246
        assert ~[~[1u,2u,3u],~[2u,3u,4u],~[3u,4u,5u],~[4u,5u,6u]]
            == windowed (3u, ~[1u,2u,3u,4u,5u,6u]);
2247

2248 2249
        assert ~[~[1u,2u,3u,4u],~[2u,3u,4u,5u],~[3u,4u,5u,6u]]
            == windowed (4u, ~[1u,2u,3u,4u,5u,6u]);
2250

2251
        assert ~[] == windowed (7u, ~[1u,2u,3u,4u,5u,6u]);
2252 2253 2254 2255
    }

    #[test]
    #[should_fail]
2256
    #[ignore(cfg(windows))]
2257
    fn test_windowed_() {
2258
        let _x = windowed (0u, ~[1u,2u,3u,4u,5u,6u]);
2259
    }
2260 2261

    #[test]
2262 2263
    fn to_mut_no_copy() {
        unsafe {
2264
            let x = ~[1, 2, 3];
2265 2266 2267 2268 2269
            let addr = unsafe::to_ptr(x);
            let x_mut = to_mut(x);
            let addr_mut = unsafe::to_ptr(x_mut);
            assert addr == addr_mut;
        }
2270 2271 2272
    }

    #[test]
2273 2274
    fn from_mut_no_copy() {
        unsafe {
2275
            let x = ~[mut 1, 2, 3];
2276 2277 2278 2279 2280
            let addr = unsafe::to_ptr(x);
            let x_imm = from_mut(x);
            let addr_imm = unsafe::to_ptr(x_imm);
            assert addr == addr_imm;
        }
2281
    }
B
Brian Anderson 已提交
2282

E
Eric Holk 已提交
2283 2284
    #[test]
    fn test_unshift() {
2285
        let mut x = ~[1, 2, 3];
E
Eric Holk 已提交
2286
        unshift(x, 0);
2287
        assert x == ~[0, 1, 2, 3];
E
Eric Holk 已提交
2288 2289
    }

B
Brian Anderson 已提交
2290 2291
    #[test]
    fn test_capacity() {
2292
        let mut v = ~[0u64];
B
Brian Anderson 已提交
2293 2294
        reserve(v, 10u);
        assert capacity(v) == 10u;
2295
        let mut v = ~[0u32];
B
Brian Anderson 已提交
2296 2297 2298
        reserve(v, 10u);
        assert capacity(v) == 10u;
    }
2299 2300 2301

    #[test]
    fn test_view() {
2302
        let v = ~[1, 2, 3, 4, 5];
2303 2304 2305 2306 2307
        let v = view(v, 1u, 3u);
        assert(len(v) == 2u);
        assert(v[0] == 2);
        assert(v[1] == 3);
    }
2308 2309
}

2310 2311 2312 2313 2314 2315 2316
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End: