vec.rs 61.8 KB
Newer Older
B
Brian Anderson 已提交
1 2
#[doc = "Vectors"];

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

87 88
#[abi = "cdecl"]
native mod rustrt {
89 90 91 92 93 94
    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;
95 96
}

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

B
Brian Anderson 已提交
102
#[doc = "A function used to initialize the elements of a vector"]
N
Niko Matsakis 已提交
103
type init_op<T> = fn(uint) -> T;
104

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

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

B
Brian Anderson 已提交
115
#[doc = "Returns true if two vectors have the same length"]
116
pure fn same_length<T, U>(xs: &[const T], ys: &[const U]) -> bool {
117
    len(xs) == len(ys)
118 119
}

B
Brian Anderson 已提交
120
#[doc = "
121
Reserves capacity for exactly `n` elements in the given vector.
122 123 124 125

If the capacity for `v` is already equal to or greater than the requested
capacity, then no action is taken.

B
Brian Anderson 已提交
126
# Arguments
127

B
Brian Anderson 已提交
128 129 130
* v - A vector
* n - The number of elements to reserve space for
"]
131
fn reserve<T>(&v: ~[const T], n: uint) {
132 133
    // Only make the (slow) call into the runtime if we have to
    if capacity(v) < n {
134
        let ptr = ptr::addr_of(v) as **unsafe::vec_repr;
135 136
        rustrt::vec_reserve_shared(sys::get_type_desc::<T>(),
                                   ptr, n as size_t);
137
    }
138 139
}

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
#[doc = "
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
"]
155
fn reserve_at_least<T>(&v: ~[const T], n: uint) {
156 157 158
    reserve(v, uint::next_power_of_two(n));
}

B
Brian Anderson 已提交
159 160 161
#[doc = "
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
}

B
Brian Anderson 已提交
170
#[doc = "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

B
Brian Anderson 已提交
176
#[doc = "
177 178 179 180
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`.
B
Brian Anderson 已提交
181
"]
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;
}

B
Brian Anderson 已提交
190
#[doc = "
191 192 193 194
Creates and initializes an immutable vector.

Creates an immutable vector of size `n_elts` and initializes the elements
to the value `t`.
B
Brian Anderson 已提交
195
"]
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;
}

G
Graydon Hoare 已提交
206
#[doc = "Produces a mut vector from an immutable vector."]
207
fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
208
    unsafe { ::unsafe::transmute(v) }
209 210
}

G
Graydon Hoare 已提交
211
#[doc = "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

B
Brian Anderson 已提交
218
#[doc = "Returns the first element of a vector"]
219
pure fn head<T: copy>(v: &[const T]) -> T { v[0] }
220

221
#[doc = "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
#[doc = "Returns a vector containing all but the first `n` \
         elements of a slice"]
228
pure fn tailn<T: copy>(v: &[const T], n: uint) -> ~[T] {
229 230 231
    slice(v, n, len(v))
}

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

B
Brian Anderson 已提交
238
#[doc = "
239
Returns the last element of the slice `v`, failing if the slice is empty.
B
Brian Anderson 已提交
240
"]
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
}

B
Brian Anderson 已提交
246
#[doc = "
247 248
Returns `some(x)` where `x` is the last element of the slice `v`,
or `none` if the vector is empty.
B
Brian Anderson 已提交
249
"]
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

B
Brian Anderson 已提交
255
#[doc = "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;
}

266
#[doc = "Return a slice that points into another slice."]
267
pure fn view<T: copy>(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>()))
        }
    }
}

B
Brian Anderson 已提交
278
#[doc = "
279
Split the vector `v` by applying each element against the predicate `f`.
B
Brian Anderson 已提交
280
"]
281
fn split<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[~[T]] {
282
    let ln = len(v);
283
    if (ln == 0u) { ret ~[] }
284

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

B
Brian Anderson 已提交
300
#[doc = "
301 302
Split the vector `v` by applying each element against the predicate `f` up
to `n` times.
B
Brian Anderson 已提交
303
"]
304
fn splitn<T: copy>(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] {
305
    let ln = len(v);
306
    if (ln == 0u) { ret ~[] }
307

308 309
    let mut start = 0u;
    let mut count = n;
310
    let mut result = ~[];
311
    while start < ln && count > 0u {
312
        alt position_between(v, start, ln, f) {
313 314 315 316 317 318 319 320 321 322 323 324 325
          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
}

B
Brian Anderson 已提交
326
#[doc = "
327 328
Reverse split the vector `v` by applying each element against the predicate
`f`.
B
Brian Anderson 已提交
329
"]
330
fn rsplit<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[~[T]] {
331
    let ln = len(v);
332
    if (ln == 0u) { ret ~[] }
333

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

B
Brian Anderson 已提交
349
#[doc = "
350 351
Reverse split the vector `v` by applying each element against the predicate
`f` up to `n times.
B
Brian Anderson 已提交
352
"]
353
fn rsplitn<T: copy>(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] {
354
    let ln = len(v);
355
    if (ln == 0u) { ret ~[] }
356

357 358
    let mut end = ln;
    let mut count = n;
359
    let mut result = ~[];
360
    while end > 0u && count > 0u {
361
        alt rposition_between(v, 0u, end, f) {
362 363 364 365 366 367 368 369 370 371 372 373
          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)
}
374 375 376

// Mutators

B
Brian Anderson 已提交
377
#[doc = "Removes the first element from a vector and return it"]
378
fn shift<T>(&v: ~[T]) -> T {
379 380 381
    let ln = len::<T>(v);
    assert (ln > 0u);

382
    let mut vv = ~[];
383 384 385
    v <-> vv;

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

B
Brian Anderson 已提交
391
            for uint::range(1u, ln) |i| {
392 393 394
                let r <- *ptr::offset(vv, i);
                push(v, r);
            }
395
        }
396
        unsafe::set_len(vv, 0u);
397

398
        rr
399
    }
B
Brian Anderson 已提交
400 401
}

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

B
Brian Anderson 已提交
411
#[doc = "Remove the last element from a vector and return it"]
412
fn pop<T>(&v: ~[const T]) -> T {
413
    let ln = len(v);
M
Marijn Haverbeke 已提交
414 415
    assert ln > 0u;
    let valptr = ptr::mut_addr_of(v[ln - 1u]);
416 417 418 419 420
    unsafe {
        let val <- *valptr;
        unsafe::set_len(v, ln - 1u);
        val
    }
421 422
}

B
Brian Anderson 已提交
423
#[doc = "Append an element to a vector"]
424
#[inline(always)]
425
fn push<T>(&v: ~[const T], +initval: T) {
426
    unsafe {
E
Eric Holk 已提交
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
        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);
        }
    }
}

442
fn push_slow<T>(&v: ~[const T], +initval: T) {
E
Eric Holk 已提交
443 444
    unsafe {
        let ln = v.len();
445
        reserve_at_least(v, ln + 1u);
E
Eric Holk 已提交
446 447 448 449 450 451 452
        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);
453
    }
E
Erick Tryzelaar 已提交
454 455
}

456 457
// Unchecked vector indexing
#[inline(always)]
458
unsafe fn ref<T: copy>(v: &[const T], i: uint) -> T {
B
Brian Anderson 已提交
459
    unpack_slice(v, |p, _len| *ptr::offset(p, i))
460 461
}

462
#[inline(always)]
463
fn push_all<T: copy>(&v: ~[const T], rhs: &[const T]) {
464
    reserve(v, v.len() + rhs.len());
465

B
Brian Anderson 已提交
466
    for uint::range(0u, rhs.len()) |i| {
467
        push(v, unsafe { ref(rhs, i) })
468 469
    }
}
470

471
#[inline(always)]
472
fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
473 474
    reserve(v, v.len() + rhs.len());
    unsafe {
B
Brian Anderson 已提交
475 476
        do unpack_slice(rhs) |p, len| {
            for uint::range(0, len) |i| {
477 478 479 480 481 482 483 484
                let x <- *ptr::offset(p, i);
                push(v, x);
            }
        }
        unsafe::set_len(rhs, 0);
    }
}

485
// Appending
486
#[inline(always)]
487
pure fn append<T: copy>(+lhs: ~[T], rhs: &[const T]) -> ~[T] {
488
    let mut v <- lhs;
489 490
    unchecked {
        push_all(v, rhs);
491 492 493 494
    }
    ret v;
}

E
Eric Holk 已提交
495
#[inline(always)]
496
pure fn append_one<T>(+lhs: ~[T], +x: T) -> ~[T] {
E
Eric Holk 已提交
497 498 499 500 501
    let mut v <- lhs;
    unchecked { push(v, x); }
    v
}

502
#[inline(always)]
503 504
pure fn append_mut<T: copy>(lhs: &[mut T], rhs: &[const T]) -> ~[mut T] {
    let mut v = ~[mut];
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
    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;
}
521

B
Brian Anderson 已提交
522
#[doc = "
523 524
Expands a vector in place, initializing the new elements to a given value

B
Brian Anderson 已提交
525
# Arguments
526

B
Brian Anderson 已提交
527 528 529 530
* v - The vector to grow
* n - The number of elements to add
* initval - The value for the new elements
"]
531
fn grow<T: copy>(&v: ~[const T], n: uint, initval: T) {
532
    reserve_at_least(v, len(v) + n);
533
    let mut i: uint = 0u;
534 535

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

B
Brian Anderson 已提交
538 539 540
#[doc = "
Expands a vector in place, initializing the new elements to the result of
a function
541

542
Function `init_op` is called `n` times with the values [0..`n`)
543

B
Brian Anderson 已提交
544
# Arguments
545

B
Brian Anderson 已提交
546 547 548 549 550
* 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
"]
551
fn grow_fn<T>(&v: ~[const T], n: uint, op: init_op<T>) {
552
    reserve_at_least(v, len(v) + n);
553
    let mut i: uint = 0u;
554
    while i < n { push(v, op(i)); i += 1u; }
555 556
}

B
Brian Anderson 已提交
557
#[doc = "
558 559 560 561 562 563
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.
B
Brian Anderson 已提交
564
"]
E
Eric Holk 已提交
565
#[inline(always)]
566
fn grow_set<T: copy>(&v: ~[mut T], index: uint, initval: T, val: T) {
567
    if index >= len(v) { grow(v, index - len(v) + 1u, initval); }
568 569 570 571 572 573
    v[index] = val;
}


// Functional utilities

B
Brian Anderson 已提交
574
#[doc = "
575
Apply a function to each element of a vector and return the results
B
Brian Anderson 已提交
576
"]
577 578
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> ~[U] {
    let mut result = ~[];
579
    unchecked{reserve(result, len(v));}
B
Brian Anderson 已提交
580
    for each(v) |elem| { unsafe { push(result, f(elem)); } }
581 582 583
    ret result;
}

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

B
Brian Anderson 已提交
594
#[doc = "
595
Apply a function to each element of a vector and return a concatenation
B
Brian Anderson 已提交
596 597
of each result vector
"]
598 599
pure fn flat_map<T, U>(v: &[T], f: fn(T) -> ~[U]) -> ~[U] {
    let mut result = ~[];
B
Brian Anderson 已提交
600
    for each(v) |elem| { unchecked{ push_all_move(result, f(elem)); } }
601 602 603
    ret result;
}

B
Brian Anderson 已提交
604
#[doc = "
605
Apply a function to each pair of elements and return the results
B
Brian Anderson 已提交
606
"]
607 608
pure fn map2<T: copy, U: copy, V>(v0: &[T], v1: &[U],
                                  f: fn(T, U) -> V) -> ~[V] {
609 610
    let v0_len = len(v0);
    if v0_len != len(v1) { fail; }
611
    let mut u: ~[V] = ~[];
612
    let mut i = 0u;
613 614 615 616
    while i < v0_len {
        unsafe { push(u, f(copy v0[i], copy v1[i])) };
        i += 1u;
    }
617 618 619
    ret u;
}

B
Brian Anderson 已提交
620
#[doc = "
621 622 623 624
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.
B
Brian Anderson 已提交
625
"]
626 627 628
pure fn filter_map<T, U: copy>(v: &[T], f: fn(T) -> option<U>)
    -> ~[U] {
    let mut result = ~[];
B
Brian Anderson 已提交
629
    for each(v) |elem| {
630
        alt f(elem) {
631
          none {/* no-op */ }
632
          some(result_elem) { unsafe { push(result, result_elem); } }
633 634 635 636 637
        }
    }
    ret result;
}

B
Brian Anderson 已提交
638
#[doc = "
639 640 641 642 643
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.
B
Brian Anderson 已提交
644
"]
645 646
pure fn filter<T: copy>(v: &[T], f: fn(T) -> bool) -> ~[T] {
    let mut result = ~[];
B
Brian Anderson 已提交
647
    for each(v) |elem| {
648
        if f(elem) { unsafe { push(result, elem); } }
649 650 651 652
    }
    ret result;
}

B
Brian Anderson 已提交
653 654
#[doc = "
Concatenate a vector of vectors.
655

B
Brian Anderson 已提交
656 657
Flattens a vector of vectors of T into a single vector of T.
"]
658 659
pure fn concat<T: copy>(v: &[[T]/~]) -> ~[T] {
    let mut r = ~[];
B
Brian Anderson 已提交
660
    for each(v) |inner| { unsafe { push_all(r, inner); } }
661
    ret r;
662 663
}

B
Brian Anderson 已提交
664
#[doc = "
665
Concatenate a vector of vectors, placing a given separator between each
B
Brian Anderson 已提交
666
"]
667 668
pure fn connect<T: copy>(v: &[[T]/~], sep: T) -> ~[T] {
    let mut r: ~[T] = ~[];
669
    let mut first = true;
B
Brian Anderson 已提交
670
    for each(v) |inner| {
671
        if first { first = false; } else { unsafe { push(r, sep); } }
672
        unchecked { push_all(r, inner) };
673
    }
674
    ret r;
675 676
}

B
Brian Anderson 已提交
677
#[doc = "Reduce a vector from left to right"]
678
pure fn foldl<T: copy, U>(z: T, v: &[U], p: fn(T, U) -> T) -> T {
679
    let mut accum = z;
B
Brian Anderson 已提交
680
    do iter(v) |elt| {
681 682 683 684 685
        accum = p(accum, elt);
    }
    ret accum;
}

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

B
Brian Anderson 已提交
695
#[doc = "
696 697 698
Return true if a predicate matches any elements

If the vector contains no elements then false is returned.
B
Brian Anderson 已提交
699
"]
700
pure fn any<T>(v: &[T], f: fn(T) -> bool) -> bool {
B
Brian Anderson 已提交
701
    for each(v) |elem| { if f(elem) { ret true; } }
702 703 704
    ret false;
}

B
Brian Anderson 已提交
705
#[doc = "
706 707 708
Return true if a predicate matches any elements in both vectors.

If the vectors contains no elements then false is returned.
B
Brian Anderson 已提交
709
"]
710
pure fn any2<T, U>(v0: &[T], v1: &[U],
711
                   f: fn(T, U) -> bool) -> bool {
712 713
    let v0_len = len(v0);
    let v1_len = len(v1);
714
    let mut i = 0u;
715 716 717 718 719 720 721
    while i < v0_len && i < v1_len {
        if f(v0[i], v1[i]) { ret true; };
        i += 1u;
    }
    ret false;
}

B
Brian Anderson 已提交
722
#[doc = "
723 724 725
Return true if a predicate matches all elements

If the vector contains no elements then true is returned.
B
Brian Anderson 已提交
726
"]
727
pure fn all<T>(v: &[T], f: fn(T) -> bool) -> bool {
B
Brian Anderson 已提交
728
    for each(v) |elem| { if !f(elem) { ret false; } }
729 730 731
    ret true;
}

732 733 734 735 736
#[doc = "
Return true if a predicate matches all elements

If the vector contains no elements then true is returned.
"]
737
pure fn alli<T>(v: &[T], f: fn(uint, T) -> bool) -> bool {
B
Brian Anderson 已提交
738
    for eachi(v) |i, elem| { if !f(i, elem) { ret false; } }
739 740 741
    ret true;
}

B
Brian Anderson 已提交
742
#[doc = "
743 744 745
Return true if a predicate matches all elements in both vectors.

If the vectors are not the same size then false is returned.
B
Brian Anderson 已提交
746
"]
747
pure fn all2<T, U>(v0: &[T], v1: &[U],
748
                   f: fn(T, U) -> bool) -> bool {
749 750
    let v0_len = len(v0);
    if v0_len != len(v1) { ret false; }
751
    let mut i = 0u;
752 753 754 755
    while i < v0_len { if !f(v0[i], v1[i]) { ret false; }; i += 1u; }
    ret true;
}

B
Brian Anderson 已提交
756
#[doc = "Return true if a vector contains an element with the given value"]
757
pure fn contains<T>(v: &[T], x: T) -> bool {
B
Brian Anderson 已提交
758
    for each(v) |elt| { if x == elt { ret true; } }
759 760 761
    ret false;
}

B
Brian Anderson 已提交
762
#[doc = "Returns the number of elements that are equal to a given value"]
763
pure fn count<T>(v: &[T], x: T) -> uint {
764
    let mut cnt = 0u;
B
Brian Anderson 已提交
765
    for each(v) |elt| { if x == elt { cnt += 1u; } }
766 767 768
    ret cnt;
}

B
Brian Anderson 已提交
769
#[doc = "
770
Search for the first element that matches a given predicate
771 772 773 774

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.
B
Brian Anderson 已提交
775
"]
776
pure fn find<T: copy>(v: &[T], f: fn(T) -> bool) -> option<T> {
777
    find_between(v, 0u, len(v), f)
778 779
}

B
Brian Anderson 已提交
780
#[doc = "
781 782 783 784 785
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.
B
Brian Anderson 已提交
786
"]
787
pure fn find_between<T: copy>(v: &[T], start: uint, end: uint,
788
                      f: fn(T) -> bool) -> option<T> {
B
Brian Anderson 已提交
789
    option::map(position_between(v, start, end, f), |i| v[i])
790 791
}

B
Brian Anderson 已提交
792
#[doc = "
793 794 795 796 797
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.
B
Brian Anderson 已提交
798
"]
799
pure fn rfind<T: copy>(v: &[T], f: fn(T) -> bool) -> option<T> {
800
    rfind_between(v, 0u, len(v), f)
801 802
}

B
Brian Anderson 已提交
803
#[doc = "
804 805 806 807 808
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.
B
Brian Anderson 已提交
809
"]
810
pure fn rfind_between<T: copy>(v: &[T], start: uint, end: uint,
811
                               f: fn(T) -> bool) -> option<T> {
B
Brian Anderson 已提交
812
    option::map(rposition_between(v, start, end, f), |i| v[i])
813 814
}

B
Brian Anderson 已提交
815
#[doc = "Find the first index containing a matching value"]
816
pure fn position_elem<T>(v: &[T], x: T) -> option<uint> {
B
Brian Anderson 已提交
817
    position(v, |y| x == y)
818 819
}

B
Brian Anderson 已提交
820
#[doc = "
821 822 823 824 825
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.
B
Brian Anderson 已提交
826
"]
827
pure fn position<T>(v: &[T], f: fn(T) -> bool) -> option<uint> {
828
    position_between(v, 0u, len(v), f)
829 830
}

B
Brian Anderson 已提交
831
#[doc = "
832 833 834 835 836
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.
B
Brian Anderson 已提交
837
"]
838
pure fn position_between<T>(v: &[T], start: uint, end: uint,
839
                            f: fn(T) -> bool) -> option<uint> {
840 841
    assert start <= end;
    assert end <= len(v);
842
    let mut i = start;
843
    while i < end { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
844 845 846
    ret none;
}

B
Brian Anderson 已提交
847
#[doc = "Find the last index containing a matching value"]
848
pure fn rposition_elem<T>(v: &[T], x: T) -> option<uint> {
B
Brian Anderson 已提交
849
    rposition(v, |y| x == y)
850 851
}

B
Brian Anderson 已提交
852
#[doc = "
853
Find the last index matching some predicate
854

855 856 857
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.
B
Brian Anderson 已提交
858
"]
859
pure fn rposition<T>(v: &[T], f: fn(T) -> bool) -> option<uint> {
860
    rposition_between(v, 0u, len(v), f)
861 862
}

B
Brian Anderson 已提交
863
#[doc = "
864 865 866 867 868
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.
B
Brian Anderson 已提交
869
"]
870
pure fn rposition_between<T>(v: &[T], start: uint, end: uint,
871
                             f: fn(T) -> bool) -> option<uint> {
872 873
    assert start <= end;
    assert end <= len(v);
874
    let mut i = end;
875 876 877 878
    while i > start {
        if f(v[i - 1u]) { ret some::<uint>(i - 1u); }
        i -= 1u;
    }
879 880 881 882 883 884 885
    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)
B
Brian Anderson 已提交
886
#[doc = "
887 888 889 890 891 892
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.
B
Brian Anderson 已提交
893
"]
894 895
pure fn unzip<T: copy, U: copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
    let mut as = ~[], bs = ~[];
B
Brian Anderson 已提交
896
    for each(v) |p| {
897 898 899 900 901 902
        let (a, b) = p;
        unchecked {
            vec::push(as, a);
            vec::push(bs, b);
        }
    }
903 904 905
    ret (as, bs);
}

B
Brian Anderson 已提交
906
#[doc = "
907 908 909 910
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.
B
Brian Anderson 已提交
911
"]
912 913
pure fn zip<T: copy, U: copy>(v: &[const T], u: &[const U]) -> ~[(T, U)] {
    let mut zipped = ~[];
914 915
    let sz = len(v);
    let mut i = 0u;
916
    assert sz == len(u);
917
    while i < sz unchecked { vec::push(zipped, (v[i], u[i])); i += 1u; }
918 919 920
    ret zipped;
}

B
Brian Anderson 已提交
921
#[doc = "
922 923
Swaps two elements in a vector

B
Brian Anderson 已提交
924 925 926 927 928 929
# Arguments

* v  The input vector
* a - The index of the first element
* b - The index of the second element
"]
930
fn swap<T>(&&v: ~[mut T], a: uint, b: uint) {
931 932 933
    v[a] <-> v[b];
}

B
Brian Anderson 已提交
934
#[doc = "Reverse the order of elements in a vector, in place"]
935
fn reverse<T>(v: ~[mut T]) {
936
    let mut i: uint = 0u;
937 938 939 940 941
    let ln = len::<T>(v);
    while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
}


B
Brian Anderson 已提交
942
#[doc = "Returns a vector with the order of elements reversed"]
943 944
pure fn reversed<T: copy>(v: &[const T]) -> ~[T] {
    let mut rs: ~[T] = ~[];
945
    let mut i = len::<T>(v);
946
    if i == 0u { ret rs; } else { i -= 1u; }
947 948 949 950
    unchecked {
        while i != 0u { vec::push(rs, v[i]); i -= 1u; }
        vec::push(rs, v[0]);
    }
951 952 953
    ret rs;
}

B
Brian Anderson 已提交
954
#[doc = "
955
Iterates over a slice
956

957
Iterates over slice `v` and, for each element, calls function `f` with the
958
element's value.
B
Brian Anderson 已提交
959
"]
960
#[inline(always)]
961
pure fn iter<T>(v: &[T], f: fn(T)) {
962 963 964 965 966 967
    iter_between(v, 0u, vec::len(v), f)
}

/*
Function: iter_between

968
Iterates over a slice
969

970
Iterates over slice `v` and, for each element, calls function `f` with the
971 972 973 974
element's value.

*/
#[inline(always)]
975
pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
B
Brian Anderson 已提交
976
    do unpack_slice(v) |base_ptr, len| {
977 978 979 980 981 982 983 984 985 986
        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;
            }
987 988
        }
    }
989 990
}

991 992
#[doc = "
Iterates over a vector, with option to break
993 994

Return true to continue, false to break.
995 996
"]
#[inline(always)]
997
pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
B
Brian Anderson 已提交
998
    do vec::unpack_slice(v) |p, n| {
999 1000 1001
        let mut n = n;
        let mut p = p;
        while n > 0u {
1002 1003 1004 1005
            unsafe {
                if !f(*p) { break; }
                p = ptr::offset(p, 1u);
            }
1006 1007
            n -= 1u;
        }
1008 1009 1010 1011 1012
    }
}

#[doc = "
Iterates over a vector's elements and indices
1013 1014

Return true to continue, false to break.
1015 1016
"]
#[inline(always)]
1017
pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
B
Brian Anderson 已提交
1018
    do vec::unpack_slice(v) |p, n| {
1019 1020 1021
        let mut i = 0u;
        let mut p = p;
        while i < n {
1022 1023 1024 1025
            unsafe {
                if !f(i, *p) { break; }
                p = ptr::offset(p, 1u);
            }
1026 1027
            i += 1u;
        }
1028 1029 1030
    }
}

1031 1032 1033 1034 1035 1036 1037
#[doc = "
Iterates over two vectors simultaneously

# Failure

Both vectors must have the same length
"]
1038
#[inline]
1039
fn iter2<U, T>(v1: &[U], v2: &[T], f: fn(U, T)) {
1040
    assert len(v1) == len(v2);
B
Brian Anderson 已提交
1041
    for uint::range(0u, len(v1)) |i| {
1042 1043
        f(v1[i], v2[i])
    }
1044 1045
}

B
Brian Anderson 已提交
1046
#[doc = "
1047 1048 1049 1050
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.
B
Brian Anderson 已提交
1051
"]
1052
#[inline(always)]
1053
pure fn iteri<T>(v: &[T], f: fn(uint, T)) {
1054 1055
    let mut i = 0u;
    let l = len(v);
1056 1057 1058
    while i < l { f(i, v[i]); i += 1u; }
}

B
Brian Anderson 已提交
1059
#[doc = "
1060 1061 1062 1063
Iterates over a vector in reverse

Iterates over vector `v` and, for each element, calls function `f` with the
element's value.
B
Brian Anderson 已提交
1064
"]
1065
pure fn riter<T>(v: &[T], f: fn(T)) {
B
Brian Anderson 已提交
1066
    riteri(v, |_i, v| f(v))
1067 1068
}

B
Brian Anderson 已提交
1069
#[doc ="
1070 1071 1072 1073
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.
B
Brian Anderson 已提交
1074
"]
1075
pure fn riteri<T>(v: &[T], f: fn(uint, T)) {
1076
    let mut i = len(v);
1077 1078 1079 1080 1081 1082
    while 0u < i {
        i -= 1u;
        f(i, v[i]);
    };
}

B
Brian Anderson 已提交
1083 1084
#[doc = "
Iterate over all permutations of vector `v`.
1085

B
Brian Anderson 已提交
1086 1087 1088
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).
1089 1090 1091

The total number of permutations produced is `len(v)!`.  If `v` contains
repeated elements, then some permutations are repeated.
B
Brian Anderson 已提交
1092
"]
1093
pure fn permute<T: copy>(v: &[T], put: fn(~[T])) {
1094 1095
    let ln = len(v);
    if ln == 0u {
1096
        put(~[]);
1097 1098 1099 1100 1101 1102 1103
    } 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 已提交
1104
                permute(rest, |permutation| {
1105
                    put(append(~[elt], permutation))
1106
                })
1107 1108 1109
            }
            i += 1u;
        }
1110 1111 1112
    }
}

1113 1114
pure fn windowed<TT: copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
    let mut ww = ~[];
1115
    assert 1u <= nn;
B
Brian Anderson 已提交
1116
    vec::iteri (xx, |ii, _x| {
1117
        let len = vec::len(xx);
1118 1119
        if ii+nn <= len unchecked {
            vec::push(ww, vec::slice(xx, ii, ii+nn));
1120 1121 1122
        }
    });
    ret ww;
1123 1124
}

B
Brian Anderson 已提交
1125 1126
#[doc = "
Work with the buffer of a vector.
1127

B
Brian Anderson 已提交
1128 1129 1130
Allows for unsafe manipulation of vector contents, which is useful for native
interop.
"]
1131
fn as_buf<E,T>(v: &[E], f: fn(*E) -> T) -> T {
B
Brian Anderson 已提交
1132
    unpack_slice(v, |buf, _len| f(buf))
1133 1134
}

1135
fn as_mut_buf<E,T>(v: &[mut E], f: fn(*mut E) -> T) -> T {
B
Brian Anderson 已提交
1136
    unpack_mut_slice(v, |buf, _len| f(buf))
1137 1138
}

1139 1140 1141
#[doc = "
Work with the buffer and length of a slice.
"]
1142
#[inline(always)]
1143
pure fn unpack_slice<T,U>(s: &[const T],
1144 1145 1146 1147 1148 1149
                          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>())
    }
1150 1151
}

1152 1153 1154 1155
#[doc = "
Work with the buffer and length of a slice.
"]
#[inline(always)]
1156
pure fn unpack_const_slice<T,U>(s: &[const T],
1157 1158 1159 1160 1161 1162 1163
                                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>())
    }
1164 1165 1166 1167 1168 1169
}

#[doc = "
Work with the buffer and length of a slice.
"]
#[inline(always)]
1170
pure fn unpack_mut_slice<T,U>(s: &[mut T],
1171 1172 1173 1174 1175 1176 1177
                              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>())
    }
1178 1179
}

1180
impl extensions<T: copy> for ~[T] {
1181
    #[inline(always)]
1182
    pure fn +(rhs: &[T]) -> ~[T] {
1183 1184 1185 1186
        append(self, rhs)
    }
}

1187
impl extensions<T: copy> for ~[mut T] {
1188
    #[inline(always)]
1189
    pure fn +(rhs: &[mut T]) -> ~[mut T] {
1190 1191 1192 1193
        append_mut(self, rhs)
    }
}

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

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

#[doc = "Extension methods for vectors"]
1229
impl extensions/&<T> for &[T] {
1230 1231
    #[doc = "Reduce a vector from right to left"]
    #[inline]
1232
    pure fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) }
1233 1234 1235 1236 1237 1238 1239
    #[doc = "
    Iterates over a vector

    Iterates over vector `v` and, for each element, calls function `f` with
    the element's value.
    "]
    #[inline]
1240
    pure fn iter(f: fn(T)) { iter(self, f) }
1241 1242 1243 1244 1245 1246 1247
    #[doc = "
    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.
    "]
    #[inline]
1248
    pure fn iteri(f: fn(uint, T)) { iteri(self, f) }
1249 1250 1251 1252 1253 1254 1255 1256
    #[doc = "
    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.
    "]
    #[inline]
1257
    pure fn position(f: fn(T) -> bool) -> option<uint> { position(self, f) }
1258 1259
    #[doc = "Find the first index containing a matching value"]
    #[inline]
1260
    pure fn position_elem(x: T) -> option<uint> { position_elem(self, x) }
1261 1262 1263 1264 1265 1266 1267
    #[doc = "
    Iterates over a vector in reverse

    Iterates over vector `v` and, for each element, calls function `f` with
    the element's value.
    "]
    #[inline]
1268
    pure fn riter(f: fn(T)) { riter(self, f) }
1269 1270 1271 1272 1273 1274 1275
    #[doc ="
    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.
    "]
    #[inline]
1276
    pure fn riteri(f: fn(uint, T)) { riteri(self, f) }
1277 1278 1279 1280 1281 1282 1283 1284
    #[doc = "
    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.
    "]
    #[inline]
1285
    pure fn rposition(f: fn(T) -> bool) -> option<uint> { rposition(self, f) }
1286 1287
    #[doc = "Find the last index containing a matching value"]
    #[inline]
1288
    pure fn rposition_elem(x: T) -> option<uint> { rposition_elem(self, x) }
1289
    #[doc = "
1290
    Apply a function to each element of a vector and return the results
1291 1292
    "]
    #[inline]
1293
    pure fn map<U>(f: fn(T) -> U) -> ~[U] { map(self, f) }
1294
    #[doc = "
N
Niko Matsakis 已提交
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
    }
1301 1302 1303
    #[doc = "Returns true if the function returns true for all elements.

    If the vector is empty, true is returned."]
1304
    pure fn alli(f: fn(uint, T) -> bool) -> bool {
1305 1306
        alli(self, f)
    }
N
Niko Matsakis 已提交
1307
    #[doc = "
1308 1309
    Apply a function to each element of a vector and return a concatenation
    of each result vector
1310 1311
    "]
    #[inline]
1312
    pure fn flat_map<U>(f: fn(T) -> ~[U]) -> ~[U] { flat_map(self, f) }
1313 1314 1315 1316 1317 1318 1319
    #[doc = "
    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.
    "]
    #[inline]
1320
    pure fn filter_map<U: copy>(f: fn(T) -> option<U>) -> ~[U] {
1321 1322
        filter_map(self, f)
    }
1323
}
1324

1325
#[doc = "Extension methods for vectors"]
1326
impl extensions/&<T: copy> for &[T] {
1327 1328 1329 1330 1331 1332 1333 1334
    #[doc = "
    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.
    "]
    #[inline]
1335
    pure fn filter(f: fn(T) -> bool) -> ~[T] { filter(self, f) }
1336 1337 1338 1339 1340 1341 1342 1343
    #[doc = "
    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.
    "]
    #[inline]
1344
    pure fn find(f: fn(T) -> bool) -> option<T> { find(self, f) }
1345 1346 1347 1348 1349 1350 1351 1352
    #[doc = "
    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.
    "]
    #[inline]
1353
    pure fn rfind(f: fn(T) -> bool) -> option<T> { rfind(self, f) }
1354 1355
}

B
Brian Anderson 已提交
1356
#[doc = "Unsafe operations"]
1357
mod unsafe {
T
Tim Chevalier 已提交
1358
    // FIXME: This should have crate visibility (#1893 blocks that)
B
Brian Anderson 已提交
1359
    #[doc = "The internal representation of a vector"]
1360 1361 1362 1363 1364 1365
    type vec_repr = {
        box_header: (uint, uint, uint, uint),
        mut fill: uint,
        mut alloc: uint,
        data: u8
    };
1366

B
Brian Anderson 已提交
1367
    #[doc = "
1368 1369
    Constructs a vector from an unsafe pointer to a buffer

B
Brian Anderson 已提交
1370
    # Arguments
1371

B
Brian Anderson 已提交
1372 1373 1374
    * ptr - An unsafe pointer to a buffer of `T`
    * elts - The number of elements in the buffer
    "]
1375
    #[inline(always)]
1376
    unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
1377 1378 1379
        ret ::unsafe::reinterpret_cast(
            rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
                                        ptr as *(),
1380
                                        elts as size_t));
1381 1382
    }

B
Brian Anderson 已提交
1383
    #[doc = "
1384 1385
    Sets the length of a vector

1386
    This will explicitly set the size of the vector, without actually
1387 1388
    modifing its buffers, so it is up to the caller to ensure that
    the vector is actually the specified size.
B
Brian Anderson 已提交
1389
    "]
1390
    #[inline(always)]
1391
    unsafe fn set_len<T>(&&v: ~[const T], new_len: uint) {
1392 1393 1394 1395
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        (**repr).fill = new_len * sys::size_of::<T>();
    }

B
Brian Anderson 已提交
1396
    #[doc = "
1397 1398 1399 1400 1401 1402 1403
    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.
B
Brian Anderson 已提交
1404
    "]
1405
    #[inline(always)]
1406
    unsafe fn to_ptr<T>(v: ~[const T]) -> *T {
1407 1408 1409
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
    }
1410 1411 1412 1413 1414 1415


    #[doc = "
    Form a slice from a pointer and length (as a number of units, not bytes).
    "]
    #[inline(always)]
1416
    unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn(&& &[T]) -> U) -> U {
1417
        let pair = (p, len * sys::size_of::<T>());
1418
        let v : *(&blk.[T]) =
1419
            ::unsafe::reinterpret_cast(ptr::addr_of(pair));
1420 1421
        f(*v)
    }
1422 1423
}

B
Brian Anderson 已提交
1424
#[doc = "Operations on `[u8]`"]
1425 1426 1427 1428 1429
mod u8 {
    export cmp;
    export lt, le, eq, ne, ge, gt;
    export hash;

B
Brian Anderson 已提交
1430
    #[doc = "Bytewise string comparison"]
1431
    pure fn cmp(&&a: ~[u8], &&b: ~[u8]) -> int {
1432 1433
        let a_len = len(a);
        let b_len = len(b);
1434
        let n = uint::min(a_len, b_len) as libc::size_t;
1435 1436 1437 1438
        let r = unsafe {
            libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
                         unsafe::to_ptr(b) as *libc::c_void, n) as int
        };
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450

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

B
Brian Anderson 已提交
1451
    #[doc = "Bytewise less than or equal"]
1452
    pure fn lt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) < 0 }
1453

B
Brian Anderson 已提交
1454
    #[doc = "Bytewise less than or equal"]
1455
    pure fn le(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) <= 0 }
1456

B
Brian Anderson 已提交
1457
    #[doc = "Bytewise equality"]
1458
    pure fn eq(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) == 0 } }
1459

B
Brian Anderson 已提交
1460
    #[doc = "Bytewise inequality"]
1461
    pure fn ne(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) != 0 } }
1462

B
Brian Anderson 已提交
1463
    #[doc ="Bytewise greater than or equal"]
1464
    pure fn ge(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) >= 0 }
1465

B
Brian Anderson 已提交
1466
    #[doc = "Bytewise greater than"]
1467
    pure fn gt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) > 0 }
1468

B
Brian Anderson 已提交
1469
    #[doc = "String hash function"]
1470
    fn hash(&&s: ~[u8]) -> uint {
T
Tim Chevalier 已提交
1471 1472 1473
        /* 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 */
1474

1475
        let mut u: uint = 5381u;
B
Brian Anderson 已提交
1476
        vec::iter(s, |c| {u *= 33u; u += c as uint;});
1477 1478 1479 1480
        ret u;
    }
}

1481 1482 1483 1484 1485
// ___________________________________________________________________________
// ITERATION TRAIT METHODS
//
// This cannot be used with iter-trait.rs because of the region pointer
// required in the slice.
1486
impl extensions/&<A> of iter::base_iter<A> for &[const A] {
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
    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) }
}
1498 1499
impl extensions/&<A:copy> for &[const A] {
    fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
1500 1501
        iter::filter_to_vec(self, pred)
    }
1502 1503
    fn map_to_vec<B>(op: fn(A) -> B) -> ~[B] { iter::map_to_vec(self, op) }
    fn to_vec() -> ~[A] { iter::to_vec(self) }
1504

T
Tim Chevalier 已提交
1505
    // FIXME--bug in resolve prevents this from working (#2611)
1506
    // fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> ~[B] {
1507 1508 1509 1510 1511 1512 1513 1514
    //     iter::flat_map_to_vec(self, op)
    // }

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

1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
#[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; }

1528
    fn square_if_odd(&&n: uint) -> option<uint> {
1529 1530 1531 1532 1533 1534
        ret if n % 2u == 1u { some(n * n) } else { none };
    }

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

    #[test]
1535 1536 1537
    fn test_unsafe_ptrs() {
        unsafe {
            // Test on-stack copy-from-buf.
1538
            let a = ~[1, 2, 3];
1539 1540 1541 1542 1543 1544 1545 1546
            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.
1547
            let c = ~[1, 2, 3, 4, 5];
1548 1549 1550 1551 1552 1553 1554 1555 1556
            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);
        }
1557 1558 1559
    }

    #[test]
1560 1561
    fn test_from_fn() {
        // Test on-stack from_fn.
1562
        let mut v = from_fn(3u, square);
1563 1564 1565 1566 1567
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);

1568 1569
        // Test on-heap from_fn.
        v = from_fn(5u, square);
1570 1571 1572 1573 1574 1575 1576 1577 1578
        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]
1579 1580
    fn test_from_elem() {
        // Test on-stack from_elem.
1581
        let mut v = from_elem(2u, 10u);
1582 1583 1584 1585
        assert (len(v) == 2u);
        assert (v[0] == 10u);
        assert (v[1] == 10u);

1586 1587
        // Test on-heap from_elem.
        v = from_elem(6u, 20u);
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597
        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() {
1598 1599
        assert (is_empty::<int>(~[]));
        assert (!is_empty(~[0]));
1600 1601 1602 1603
    }

    #[test]
    fn test_is_not_empty() {
1604 1605
        assert (is_not_empty(~[0]));
        assert (!is_not_empty::<int>(~[]));
1606 1607 1608 1609
    }

    #[test]
    fn test_head() {
1610
        let a = ~[11, 12];
1611 1612 1613 1614 1615
        assert (head(a) == 11);
    }

    #[test]
    fn test_tail() {
1616 1617
        let mut a = ~[11];
        assert (tail(a) == ~[]);
1618

1619 1620
        a = ~[11, 12];
        assert (tail(a) == ~[12]);
1621 1622 1623 1624
    }

    #[test]
    fn test_last() {
1625
        let mut n = last_opt(~[]);
1626
        assert (n == none);
1627
        n = last_opt(~[1, 2, 3]);
1628
        assert (n == some(3));
1629
        n = last_opt(~[1, 2, 3, 4, 5]);
1630 1631 1632 1633 1634 1635
        assert (n == some(5));
    }

    #[test]
    fn test_slice() {
        // Test on-stack -> on-stack slice.
1636
        let mut v = slice(~[1, 2, 3], 1u, 3u);
1637 1638 1639 1640 1641
        assert (len(v) == 2u);
        assert (v[0] == 2);
        assert (v[1] == 3);

        // Test on-heap -> on-stack slice.
1642
        v = slice(~[1, 2, 3, 4, 5], 0u, 3u);
1643 1644 1645 1646 1647 1648
        assert (len(v) == 3u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);

        // Test on-heap -> on-heap slice.
1649
        v = slice(~[1, 2, 3, 4, 5, 6], 1u, 6u);
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660
        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.
1661
        let mut v = ~[1, 2, 3];
1662
        let mut e = pop(v);
1663 1664 1665 1666 1667 1668
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (e == 3);

        // Test on-heap pop.
1669
        v = ~[1, 2, 3, 4, 5];
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
        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().
1682
        let mut v = ~[];
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
        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().
1697
        let mut v = ~[];
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
        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() {
1715
        let mut v = ~[];
1716 1717 1718 1719 1720 1721 1722 1723 1724
        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() {
1725
        let mut v = ~[mut 1, 2, 3];
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
        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.
1738
        let mut v = ~[1u, 2u, 3u];
1739
        let mut w = map(v, square_ref);
1740 1741 1742 1743 1744 1745
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);

        // Test on-heap map.
1746
        v = ~[1u, 2u, 3u, 4u, 5u];
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
        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;
1760 1761
        let v0 = ~[1, 2, 3, 4, 5];
        let v1 = ~[5, 4, 3, 2, 1];
1762
        let u = map2::<int, int, int>(v0, v1, f);
1763
        let mut i = 0;
1764 1765 1766 1767 1768 1769
        while i < 5 { assert (v0[i] * v1[i] == u[i]); i += 1; }
    }

    #[test]
    fn test_filter_map() {
        // Test on-stack filter-map.
1770
        let mut v = ~[1u, 2u, 3u];
1771
        let mut w = filter_map(v, square_if_odd);
1772 1773 1774 1775 1776
        assert (len(w) == 2u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);

        // Test on-heap filter-map.
1777
        v = ~[1u, 2u, 3u, 4u, 5u];
1778 1779 1780 1781 1782 1783
        w = filter_map(v, square_if_odd);
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);
        assert (w[2] == 25u);

1784
        fn halve(&&i: int) -> option<int> {
1785 1786 1787 1788 1789
            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; }
1790 1791 1792 1793 1794
        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];
1795
        assert (filter_map(all_even, halve) == map(all_even, halve_for_sure));
1796 1797
        assert (filter_map(all_odd1, halve) == ~[]);
        assert (filter_map(all_odd2, halve) == ~[]);
1798 1799 1800 1801 1802
        assert (filter_map(mix, halve) == mix_dest);
    }

    #[test]
    fn test_filter() {
1803 1804
        assert filter(~[1u, 2u, 3u], is_odd) == ~[1u, 3u];
        assert filter(~[1u, 2u, 4u, 8u, 16u], is_three) == ~[];
1805 1806 1807 1808 1809
    }

    #[test]
    fn test_foldl() {
        // Test on-stack fold.
1810
        let mut v = ~[1u, 2u, 3u];
1811
        let mut sum = foldl(0u, v, add);
1812 1813 1814
        assert (sum == 6u);

        // Test on-heap fold.
1815
        v = ~[1u, 2u, 3u, 4u, 5u];
1816 1817 1818 1819 1820 1821 1822 1823 1824
        sum = foldl(0u, v, add);
        assert (sum == 15u);
    }

    #[test]
    fn test_foldl2() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1825
        let mut v = ~[1, 2, 3, 4];
1826 1827 1828 1829 1830 1831 1832 1833 1834
        let sum = foldl(0, v, sub);
        assert sum == -10;
    }

    #[test]
    fn test_foldr() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1835
        let mut v = ~[1, 2, 3, 4];
1836 1837 1838 1839 1840 1841
        let sum = foldr(v, 0, sub);
        assert sum == -2;
    }

    #[test]
    fn test_iter_empty() {
1842
        let mut i = 0;
B
Brian Anderson 已提交
1843
        iter::<int>(~[], |_v| i += 1);
1844 1845 1846 1847 1848
        assert i == 0;
    }

    #[test]
    fn test_iter_nonempty() {
1849
        let mut i = 0;
B
Brian Anderson 已提交
1850
        iter(~[1, 2, 3], |v| i += v);
1851 1852 1853 1854 1855
        assert i == 6;
    }

    #[test]
    fn test_iteri() {
1856
        let mut i = 0;
B
Brian Anderson 已提交
1857
        iteri(~[1, 2, 3], |j, v| {
1858 1859 1860 1861 1862 1863 1864 1865 1866
            if i == 0 { assert v == 1; }
            assert j + 1u == v as uint;
            i += v;
        });
        assert i == 6;
    }

    #[test]
    fn test_riter_empty() {
1867
        let mut i = 0;
B
Brian Anderson 已提交
1868
        riter::<int>(~[], |_v| i += 1);
1869 1870 1871 1872 1873
        assert i == 0;
    }

    #[test]
    fn test_riter_nonempty() {
1874
        let mut i = 0;
B
Brian Anderson 已提交
1875
        riter(~[1, 2, 3], |v| {
1876 1877 1878 1879 1880 1881 1882 1883
            if i == 0 { assert v == 3; }
            i += v
        });
        assert i == 6;
    }

    #[test]
    fn test_riteri() {
1884
        let mut i = 0;
B
Brian Anderson 已提交
1885
        riteri(~[0, 1, 2], |j, v| {
1886 1887 1888 1889 1890 1891 1892 1893 1894
            if i == 0 { assert v == 2; }
            assert j == v as uint;
            i += v;
        });
        assert i == 3;
    }

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

1897
        results = ~[];
B
Brian Anderson 已提交
1898
        permute(~[], |v| vec::push(results, v));
1899
        assert results == ~[~[]];
1900

1901
        results = ~[];
B
Brian Anderson 已提交
1902
        permute(~[7], |v| results += ~[v]);
1903
        assert results == ~[~[7]];
1904

1905
        results = ~[];
B
Brian Anderson 已提交
1906
        permute(~[1,1], |v| results += ~[v]);
1907
        assert results == ~[~[1,1],~[1,1]];
1908

1909
        results = ~[];
B
Brian Anderson 已提交
1910
        permute(~[5,2,0], |v| results += ~[v]);
1911
        assert results ==
1912
            ~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]];
1913 1914 1915 1916
    }

    #[test]
    fn test_any_and_all() {
1917 1918 1919 1920
        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));
1921

1922 1923 1924 1925
        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));
1926 1927 1928 1929 1930
    }

    #[test]
    fn test_any2_and_all2() {

1931 1932 1933 1934
        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));
1935

1936 1937 1938 1939
        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));
1940 1941 1942 1943
    }

    #[test]
    fn test_zip_unzip() {
1944 1945
        let v1 = ~[1, 2, 3];
        let v2 = ~[4, 5, 6];
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960

        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]
1961
    fn test_position_elem() {
1962
        assert position_elem(~[], 1) == none;
1963

1964
        let v1 = ~[1, 2, 3, 3, 2, 5];
1965 1966 1967 1968
        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;
1969 1970 1971
    }

    #[test]
1972
    fn test_position() {
1973 1974
        fn less_than_three(&&i: int) -> bool { ret i < 3; }
        fn is_eighteen(&&i: int) -> bool { ret i == 18; }
1975

1976
        assert position(~[], less_than_three) == none;
1977

1978
        let v1 = ~[5, 4, 3, 2, 1];
1979 1980
        assert position(v1, less_than_three) == some(3u);
        assert position(v1, is_eighteen) == none;
1981 1982 1983
    }

    #[test]
1984
    fn test_position_between() {
1985
        assert position_between(~[], 0u, 0u, f) == none;
1986 1987

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

1990 1991 1992 1993 1994
        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);
1995

1996 1997 1998 1999
        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);
2000

2001 2002 2003
        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);
2004

2005 2006
        assert position_between(v, 3u, 3u, f) == none;
        assert position_between(v, 3u, 4u, f) == some(3u);
2007

2008
        assert position_between(v, 4u, 4u, f) == none;
2009 2010
    }

2011 2012
    #[test]
    fn test_find() {
2013
        assert find(~[], f) == none;
2014 2015 2016

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2017
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2018 2019 2020 2021 2022 2023

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

    #[test]
2024
    fn test_find_between() {
2025
        assert find_between(~[], 0u, 0u, f) == none;
2026 2027

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

2030 2031 2032 2033 2034
        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'));
2035

2036 2037 2038 2039
        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'));
2040

2041 2042 2043
        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'));
2044

2045 2046
        assert find_between(v, 3u, 3u, f) == none;
        assert find_between(v, 3u, 4u, f) == some((3, 'b'));
2047

2048
        assert find_between(v, 4u, 4u, f) == none;
2049 2050
    }

2051 2052
    #[test]
    fn test_rposition() {
2053
        assert find(~[], f) == none;
2054 2055 2056

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2057
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2058 2059 2060 2061 2062 2063

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

    #[test]
2064
    fn test_rposition_between() {
2065
        assert rposition_between(~[], 0u, 0u, f) == none;
2066 2067

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

2070 2071 2072 2073 2074
        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);
2075

2076 2077 2078 2079
        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);
2080

2081 2082 2083
        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);
2084

2085 2086
        assert rposition_between(v, 3u, 3u, f) == none;
        assert rposition_between(v, 3u, 4u, f) == some(3u);
2087

2088
        assert rposition_between(v, 4u, 4u, f) == none;
2089
    }
2090 2091 2092

    #[test]
    fn test_rfind() {
2093
        assert rfind(~[], f) == none;
2094 2095 2096

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
2097
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
2098 2099 2100 2101 2102 2103

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

    #[test]
2104
    fn test_rfind_between() {
2105
        assert rfind_between(~[], 0u, 0u, f) == none;
2106 2107

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

2110 2111 2112 2113 2114
        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'));
2115

2116 2117 2118 2119
        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'));
2120

2121 2122 2123
        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'));
2124

2125 2126
        assert rfind_between(v, 3u, 3u, f) == none;
        assert rfind_between(v, 3u, 4u, f) == some((3, 'b'));
2127

2128
        assert rfind_between(v, 4u, 4u, f) == none;
2129 2130 2131 2132
    }

    #[test]
    fn reverse_and_reversed() {
2133
        let v: ~[mut int] = ~[mut 10, 20];
2134 2135 2136 2137 2138
        assert (v[0] == 10);
        assert (v[1] == 20);
        reverse(v);
        assert (v[0] == 20);
        assert (v[1] == 10);
2139
        let v2 = reversed::<int>(~[10, 20]);
2140 2141 2142 2143 2144 2145
        assert (v2[0] == 20);
        assert (v2[1] == 10);
        v[0] = 30;
        assert (v2[0] == 20);
        // Make sure they work with 0-length vectors too.

2146 2147 2148
        let v4 = reversed::<int>(~[]);
        assert (v4 == ~[]);
        let v3: ~[mut int] = ~[mut];
2149 2150 2151 2152 2153
        reverse::<int>(v3);
    }

    #[test]
    fn reversed_mut() {
2154
        let v2 = reversed::<int>(~[mut 10, 20]);
2155 2156 2157 2158 2159 2160
        assert (v2[0] == 20);
        assert (v2[1] == 10);
    }

    #[test]
    fn test_init() {
2161 2162
        let v = init(~[1, 2, 3]);
        assert v == ~[1, 2];
2163 2164
    }

2165 2166 2167 2168
    #[test]
    fn test_split() {
        fn f(&&x: int) -> bool { x == 3 }

2169 2170 2171 2172 2173
        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]];
2174 2175 2176 2177 2178 2179
    }

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

2180 2181 2182 2183 2184 2185
        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]];
2186 2187 2188 2189 2190 2191
    }

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

2192 2193 2194 2195
        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]];
2196 2197 2198 2199 2200 2201
    }

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

2202 2203 2204 2205 2206
        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]];
2207 2208
    }

2209
    #[test]
B
Brian Anderson 已提交
2210
    #[should_fail]
2211
    #[ignore(cfg(windows))]
2212
    fn test_init_empty() {
2213
        init::<int>(~[]);
2214 2215 2216 2217
    }

    #[test]
    fn test_concat() {
2218
        assert concat(~[~[1], ~[2,3]]) == ~[1, 2, 3];
2219 2220
    }

2221 2222
    #[test]
    fn test_connect() {
2223 2224 2225
        assert connect(~[], 0) == ~[];
        assert connect(~[~[1], ~[2, 3]], 0) == ~[1, 0, 2, 3];
        assert connect(~[~[1], ~[2], ~[3]], 0) == ~[1, 0, 2, 0, 3];
2226 2227
    }

2228 2229
    #[test]
    fn test_windowed () {
2230 2231
        assert ~[~[1u,2u,3u],~[2u,3u,4u],~[3u,4u,5u],~[4u,5u,6u]]
            == windowed (3u, ~[1u,2u,3u,4u,5u,6u]);
2232

2233 2234
        assert ~[~[1u,2u,3u,4u],~[2u,3u,4u,5u],~[3u,4u,5u,6u]]
            == windowed (4u, ~[1u,2u,3u,4u,5u,6u]);
2235

2236
        assert ~[] == windowed (7u, ~[1u,2u,3u,4u,5u,6u]);
2237 2238 2239 2240
    }

    #[test]
    #[should_fail]
2241
    #[ignore(cfg(windows))]
2242
    fn test_windowed_() {
2243
        let _x = windowed (0u, ~[1u,2u,3u,4u,5u,6u]);
2244
    }
2245 2246

    #[test]
2247 2248
    fn to_mut_no_copy() {
        unsafe {
2249
            let x = ~[1, 2, 3];
2250 2251 2252 2253 2254
            let addr = unsafe::to_ptr(x);
            let x_mut = to_mut(x);
            let addr_mut = unsafe::to_ptr(x_mut);
            assert addr == addr_mut;
        }
2255 2256 2257
    }

    #[test]
2258 2259
    fn from_mut_no_copy() {
        unsafe {
2260
            let x = ~[mut 1, 2, 3];
2261 2262 2263 2264 2265
            let addr = unsafe::to_ptr(x);
            let x_imm = from_mut(x);
            let addr_imm = unsafe::to_ptr(x_imm);
            assert addr == addr_imm;
        }
2266
    }
B
Brian Anderson 已提交
2267

E
Eric Holk 已提交
2268 2269
    #[test]
    fn test_unshift() {
2270
        let mut x = ~[1, 2, 3];
E
Eric Holk 已提交
2271
        unshift(x, 0);
2272
        assert x == ~[0, 1, 2, 3];
E
Eric Holk 已提交
2273 2274
    }

B
Brian Anderson 已提交
2275 2276
    #[test]
    fn test_capacity() {
2277
        let mut v = ~[0u64];
B
Brian Anderson 已提交
2278 2279
        reserve(v, 10u);
        assert capacity(v) == 10u;
2280
        let mut v = ~[0u32];
B
Brian Anderson 已提交
2281 2282 2283
        reserve(v, 10u);
        assert capacity(v) == 10u;
    }
2284 2285 2286

    #[test]
    fn test_view() {
2287
        let v = ~[1, 2, 3, 4, 5];
2288 2289 2290 2291 2292
        let v = view(v, 1u, 3u);
        assert(len(v) == 2u);
        assert(v[0] == 2);
        assert(v[1] == 3);
    }
2293 2294
}

2295 2296 2297 2298 2299 2300 2301
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End: