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

3 4 5 6
import option::{some, none};
import uint::next_power_of_two;
import ptr::addr_of;

7 8 9 10 11 12
export init_op;
export is_empty;
export is_not_empty;
export same_length;
export reserve;
export len;
13 14
export from_fn;
export from_elem;
15 16 17 18
export to_mut;
export from_mut;
export head;
export tail;
19
export tailn;
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
export init;
export last;
export last_opt;
export slice;
export split;
export splitn;
export rsplit;
export rsplitn;
export shift;
export pop;
export push;
export grow;
export grow_fn;
export grow_set;
export map;
export map2;
36
export flat_map;
37 38 39 40 41 42 43 44 45 46 47 48 49
export filter_map;
export filter;
export concat;
export connect;
export foldl;
export foldr;
export any;
export any2;
export all;
export all2;
export contains;
export count;
export find;
50
export find_between;
51
export rfind;
52
export rfind_between;
53
export position_elem;
54
export position;
55
export position_between;
56
export position_elem;
57
export rposition;
58
export rposition_between;
59 60 61 62 63
export unzip;
export zip;
export swap;
export reverse;
export reversed;
64
export iter, each, eachi;
65 66 67 68 69 70 71 72 73 74 75 76
export iter2;
export iteri;
export riter;
export riteri;
export permute;
export windowed;
export as_buf;
export as_mut_buf;
export vec_len;
export unsafe;
export u8;

77 78 79 80
#[abi = "cdecl"]
native mod rustrt {
    fn vec_reserve_shared<T>(t: *sys::type_desc,
                             &v: [const T],
81
                             n: libc::size_t);
82 83
    fn vec_from_buf_shared<T>(t: *sys::type_desc,
                              ptr: *T,
84
                              count: libc::size_t) -> [T];
85 86
}

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

B
Brian Anderson 已提交
90
#[doc = "Returns true if a vector contains no elements"]
91
pure fn is_empty<T>(v: [const T]) -> bool {
92
    len(v) == 0u
93 94
}

B
Brian Anderson 已提交
95
#[doc = "Returns true if a vector contains some elements"]
96 97
pure fn is_not_empty<T>(v: [const T]) -> bool { ret !is_empty(v); }

B
Brian Anderson 已提交
98
#[doc = "Returns true if two vectors have the same length"]
99
pure fn same_length<T, U>(xs: [const T], ys: [const U]) -> bool {
100 101 102
    vec::len(xs) == vec::len(ys)
}

B
Brian Anderson 已提交
103
#[doc = "
104
Reserves capacity for exactly `n` elements in the given vector.
105 106 107 108

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

B
Brian Anderson 已提交
109
# Arguments
110

B
Brian Anderson 已提交
111 112 113
* v - A vector
* n - The number of elements to reserve space for
"]
114 115 116 117
fn reserve<T>(&v: [const T], n: uint) {
    rustrt::vec_reserve_shared(sys::get_type_desc::<T>(), v, n);
}

B
Brian Anderson 已提交
118
#[doc = "Returns the length of a vector"]
119
#[inline(always)]
120 121 122 123
pure fn len<T>(&&v: [const T]) -> uint unsafe {
    let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
    (**repr).fill / sys::size_of::<T>()
}
124

B
Brian Anderson 已提交
125
#[doc = "
126 127 128 129
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 已提交
130
"]
131
fn from_fn<T>(n_elts: uint, op: init_op<T>) -> [T] {
132
    let mut v = [];
133
    reserve(v, n_elts);
134
    let mut i: uint = 0u;
135 136 137 138
    while i < n_elts { v += [op(i)]; i += 1u; }
    ret v;
}

B
Brian Anderson 已提交
139
#[doc = "
140 141 142 143
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 已提交
144
"]
145
fn from_elem<T: copy>(n_elts: uint, t: T) -> [T] {
146
    let mut v = [];
147
    reserve(v, n_elts);
148
    let mut i: uint = 0u;
149 150 151 152
    while i < n_elts { v += [t]; i += 1u; }
    ret v;
}

G
Graydon Hoare 已提交
153 154
#[doc = "Produces a mut vector from an immutable vector."]
fn to_mut<T>(+v: [T]) -> [mut T] unsafe {
M
Marijn Haverbeke 已提交
155
    let r = ::unsafe::reinterpret_cast(v);
156
    ::unsafe::forget(v);
M
Marijn Haverbeke 已提交
157
    r
158 159
}

G
Graydon Hoare 已提交
160 161
#[doc = "Produces an immutable vector from a mut vector."]
fn from_mut<T>(+v: [mut T]) -> [T] unsafe {
M
Marijn Haverbeke 已提交
162
    let r = ::unsafe::reinterpret_cast(v);
163
    ::unsafe::forget(v);
M
Marijn Haverbeke 已提交
164
    r
165 166
}

167 168 169 170 171 172 173
// This function only exists to work around bugs in the type checker.
fn from_const<T>(+v: [const T]) -> [T] unsafe {
    let r = ::unsafe::reinterpret_cast(v);
    ::unsafe::forget(v);
    r
}

174 175
// Accessors

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

B
Brian Anderson 已提交
179
#[doc = "Returns all but the first element of a vector"]
180
fn tail<T: copy>(v: [const T]) -> [T] {
181 182 183
    ret slice(v, 1u, len(v));
}

B
Brian Anderson 已提交
184
#[doc = "Returns all but the first `n` elements of a vector"]
185
fn tailn<T: copy>(v: [const T], n: uint) -> [T] {
186 187 188
    slice(v, n, len(v))
}

B
Brian Anderson 已提交
189
#[doc = "Returns all but the last elemnt of a vector"]
190
fn init<T: copy>(v: [const T]) -> [T] {
191 192 193 194
    assert len(v) != 0u;
    slice(v, 0u, len(v) - 1u)
}

B
Brian Anderson 已提交
195
#[doc = "
196
Returns the last element of a `v`, failing if the vector is empty.
B
Brian Anderson 已提交
197
"]
198 199 200
pure fn last<T: copy>(v: [const T]) -> T {
    if len(v) == 0u { fail "last_unsafe: empty vector" }
    v[len(v) - 1u]
201 202
}

B
Brian Anderson 已提交
203
#[doc = "
204 205
Returns some(x) where `x` is the last element of a vector `v`,
or none if the vector is empty.
B
Brian Anderson 已提交
206
"]
207
pure fn last_opt<T: copy>(v: [const T]) -> option<T> {
B
Brian Anderson 已提交
208
   if len(v) == 0u { ret none; }
209
    some(v[len(v) - 1u])
T
Tim Chevalier 已提交
210
}
211

B
Brian Anderson 已提交
212
#[doc = "Returns a copy of the elements from [`start`..`end`) from `v`."]
213
fn slice<T: copy>(v: [const T], start: uint, end: uint) -> [T] {
214 215
    assert (start <= end);
    assert (end <= len(v));
216
    let mut result = [];
217
    reserve(result, end - start);
218
    let mut i = start;
219 220 221 222
    while i < end { result += [v[i]]; i += 1u; }
    ret result;
}

B
Brian Anderson 已提交
223
#[doc = "
224
Split the vector `v` by applying each element against the predicate `f`.
B
Brian Anderson 已提交
225
"]
226
fn split<T: copy>(v: [const T], f: fn(T) -> bool) -> [[T]] {
227 228 229
    let ln = len(v);
    if (ln == 0u) { ret [] }

230 231
    let mut start = 0u;
    let mut result = [];
232
    while start < ln {
233
        alt position_between(v, start, ln, f) {
234 235 236 237 238 239 240 241 242 243 244
          none { break }
          some(i) {
            push(result, slice(v, start, i));
            start = i + 1u;
          }
        }
    }
    push(result, slice(v, start, ln));
    result
}

B
Brian Anderson 已提交
245
#[doc = "
246 247
Split the vector `v` by applying each element against the predicate `f` up
to `n` times.
B
Brian Anderson 已提交
248
"]
249
fn splitn<T: copy>(v: [const T], n: uint, f: fn(T) -> bool) -> [[T]] {
250 251 252
    let ln = len(v);
    if (ln == 0u) { ret [] }

253 254 255
    let mut start = 0u;
    let mut count = n;
    let mut result = [];
256
    while start < ln && count > 0u {
257
        alt position_between(v, start, ln, f) {
258 259 260 261 262 263 264 265 266 267 268 269 270
          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 已提交
271
#[doc = "
272 273
Reverse split the vector `v` by applying each element against the predicate
`f`.
B
Brian Anderson 已提交
274
"]
275
fn rsplit<T: copy>(v: [const T], f: fn(T) -> bool) -> [[T]] {
276 277 278
    let ln = len(v);
    if (ln == 0u) { ret [] }

279 280
    let mut end = ln;
    let mut result = [];
281
    while end > 0u {
282
        alt rposition_between(v, 0u, end, f) {
283 284 285 286 287 288 289 290 291 292 293
          none { break }
          some(i) {
            push(result, slice(v, i + 1u, end));
            end = i;
          }
        }
    }
    push(result, slice(v, 0u, end));
    reversed(result)
}

B
Brian Anderson 已提交
294
#[doc = "
295 296
Reverse split the vector `v` by applying each element against the predicate
`f` up to `n times.
B
Brian Anderson 已提交
297
"]
298
fn rsplitn<T: copy>(v: [const T], n: uint, f: fn(T) -> bool) -> [[T]] {
299 300 301
    let ln = len(v);
    if (ln == 0u) { ret [] }

302 303 304
    let mut end = ln;
    let mut count = n;
    let mut result = [];
305
    while end > 0u && count > 0u {
306
        alt rposition_between(v, 0u, end, f) {
307 308 309 310 311 312 313 314 315 316 317 318
          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)
}
319 320 321

// Mutators

B
Brian Anderson 已提交
322
#[doc = "Removes the first element from a vector and return it"]
323
fn shift<T: copy>(&v: [T]) -> T {
324 325 326 327 328 329 330
    let ln = len::<T>(v);
    assert (ln > 0u);
    let e = v[0];
    v = slice::<T>(v, 1u, ln);
    ret e;
}

B
Brian Anderson 已提交
331 332
#[doc = "Prepend an element to a vector"]
fn unshift<T: copy>(&v: [const T], +t: T) {
333 334 335
    // n.b.---for most callers, using unshift() ought not to type check, but
    // it does. It's because the type system is unaware of the mutability of
    // `v` and so allows the vector to be covariant.
B
Brian Anderson 已提交
336 337 338
    v = [const t] + v;
}

B
Brian Anderson 已提交
339
#[doc = "Remove the last element from a vector and return it"]
M
Marijn Haverbeke 已提交
340
fn pop<T>(&v: [const T]) -> T unsafe {
341
    let ln = len(v);
M
Marijn Haverbeke 已提交
342 343
    assert ln > 0u;
    let valptr = ptr::mut_addr_of(v[ln - 1u]);
344
    let val <- *valptr;
M
Marijn Haverbeke 已提交
345
    unsafe::set_len(v, ln - 1u);
346
    val
347 348
}

B
Brian Anderson 已提交
349
#[doc = "Append an element to a vector"]
350
fn push<T>(&v: [const T], +initval: T) {
B
Brian Anderson 已提交
351
    v += [initval];
E
Erick Tryzelaar 已提交
352 353
}

354 355 356

// Appending

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

B
Brian Anderson 已提交
360
# Arguments
361

B
Brian Anderson 已提交
362 363 364 365
* v - The vector to grow
* n - The number of elements to add
* initval - The value for the new elements
"]
366
fn grow<T: copy>(&v: [const T], n: uint, initval: T) {
367
    reserve(v, next_power_of_two(len(v) + n));
368
    let mut i: uint = 0u;
369 370 371
    while i < n { v += [initval]; i += 1u; }
}

B
Brian Anderson 已提交
372 373 374
#[doc = "
Expands a vector in place, initializing the new elements to the result of
a function
375

376
Function `init_op` is called `n` times with the values [0..`n`)
377

B
Brian Anderson 已提交
378
# Arguments
379

B
Brian Anderson 已提交
380 381 382 383 384
* 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
"]
385
fn grow_fn<T>(&v: [const T], n: uint, op: init_op<T>) {
386
    reserve(v, next_power_of_two(len(v) + n));
387
    let mut i: uint = 0u;
388 389 390
    while i < n { v += [op(i)]; i += 1u; }
}

B
Brian Anderson 已提交
391
#[doc = "
392 393 394 395 396 397
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 已提交
398
"]
G
Graydon Hoare 已提交
399
fn grow_set<T: copy>(&v: [mut T], index: uint, initval: T, val: T) {
400
    if index >= len(v) { grow(v, index - len(v) + 1u, initval); }
401 402 403 404 405 406
    v[index] = val;
}


// Functional utilities

B
Brian Anderson 已提交
407
#[doc = "
408
Apply a function to each element of a vector and return the results
B
Brian Anderson 已提交
409
"]
N
Niko Matsakis 已提交
410
fn map<T, U>(v: [T], f: fn(T) -> U) -> [U] {
411
    let mut result = [];
412
    reserve(result, len(v));
413
    for each(v) {|elem| result += [f(elem)]; }
414 415 416
    ret result;
}

B
Brian Anderson 已提交
417 418 419 420
#[doc = "
Apply a function eo each element of a vector and return a concatenation
of each result vector
"]
421
fn flat_map<T, U>(v: [T], f: fn(T) -> [U]) -> [U] {
422
    let mut result = [];
423
    for each(v) {|elem| result += f(elem); }
424 425 426
    ret result;
}

B
Brian Anderson 已提交
427
#[doc = "
428
Apply a function to each pair of elements and return the results
B
Brian Anderson 已提交
429
"]
430 431
fn map2<T: copy, U: copy, V>(v0: [const T], v1: [const U],
                             f: fn(T, U) -> V) -> [V] {
432 433
    let v0_len = len(v0);
    if v0_len != len(v1) { fail; }
434 435
    let mut u: [V] = [];
    let mut i = 0u;
436 437 438 439
    while i < v0_len { u += [f(copy v0[i], copy v1[i])]; i += 1u; }
    ret u;
}

B
Brian Anderson 已提交
440
#[doc = "
441 442 443 444
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 已提交
445
"]
446
fn filter_map<T, U: copy>(v: [T], f: fn(T) -> option<U>)
447
    -> [U] {
448
    let mut result = [];
449
    for each(v) {|elem|
450
        alt f(elem) {
451
          none {/* no-op */ }
452 453 454 455 456 457
          some(result_elem) { result += [result_elem]; }
        }
    }
    ret result;
}

B
Brian Anderson 已提交
458
#[doc = "
459 460 461 462 463
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 已提交
464
"]
N
Niko Matsakis 已提交
465
fn filter<T: copy>(v: [T], f: fn(T) -> bool) -> [T] {
466
    let mut result = [];
467
    for each(v) {|elem|
468 469 470 471 472
        if f(elem) { result += [elem]; }
    }
    ret result;
}

B
Brian Anderson 已提交
473 474
#[doc = "
Concatenate a vector of vectors.
475

B
Brian Anderson 已提交
476 477
Flattens a vector of vectors of T into a single vector of T.
"]
478
fn concat<T: copy>(v: [const [const T]]) -> [T] {
479
    let mut r = [];
480
    for each(v) {|inner| r += from_const(inner); }
481
    ret r;
482 483
}

B
Brian Anderson 已提交
484
#[doc = "
485
Concatenate a vector of vectors, placing a given separator between each
B
Brian Anderson 已提交
486
"]
487
fn connect<T: copy>(v: [const [const T]], sep: T) -> [T] {
488
    let mut r: [T] = [];
489
    let mut first = true;
490
    for each(v) {|inner|
491
        if first { first = false; } else { push(r, sep); }
492
        r += from_const(inner);
493
    }
494
    ret r;
495 496
}

B
Brian Anderson 已提交
497
#[doc = "Reduce a vector from left to right"]
N
Niko Matsakis 已提交
498
fn foldl<T: copy, U>(z: T, v: [const U], p: fn(T, U) -> T) -> T {
499
    let mut accum = z;
500 501 502 503 504 505
    iter(v) { |elt|
        accum = p(accum, elt);
    }
    ret accum;
}

B
Brian Anderson 已提交
506
#[doc = "Reduce a vector from right to left"]
N
Niko Matsakis 已提交
507
fn foldr<T, U: copy>(v: [const T], z: U, p: fn(T, U) -> U) -> U {
508
    let mut accum = z;
509 510 511 512 513 514
    riter(v) { |elt|
        accum = p(elt, accum);
    }
    ret accum;
}

B
Brian Anderson 已提交
515
#[doc = "
516 517 518
Return true if a predicate matches any elements

If the vector contains no elements then false is returned.
B
Brian Anderson 已提交
519
"]
N
Niko Matsakis 已提交
520
fn any<T>(v: [T], f: fn(T) -> bool) -> bool {
521
    for each(v) {|elem| if f(elem) { ret true; } }
522 523 524
    ret false;
}

B
Brian Anderson 已提交
525
#[doc = "
526 527 528
Return true if a predicate matches any elements in both vectors.

If the vectors contains no elements then false is returned.
B
Brian Anderson 已提交
529
"]
530
fn any2<T, U>(v0: [const T], v1: [U], f: fn(T, U) -> bool) -> bool {
531 532
    let v0_len = len(v0);
    let v1_len = len(v1);
533
    let mut i = 0u;
534 535 536 537 538 539 540
    while i < v0_len && i < v1_len {
        if f(v0[i], v1[i]) { ret true; };
        i += 1u;
    }
    ret false;
}

B
Brian Anderson 已提交
541
#[doc = "
542 543 544
Return true if a predicate matches all elements

If the vector contains no elements then true is returned.
B
Brian Anderson 已提交
545
"]
N
Niko Matsakis 已提交
546
fn all<T>(v: [T], f: fn(T) -> bool) -> bool {
547
    for each(v) {|elem| if !f(elem) { ret false; } }
548 549 550
    ret true;
}

B
Brian Anderson 已提交
551
#[doc = "
552 553 554
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 已提交
555
"]
556
fn all2<T, U>(v0: [const T], v1: [const U], f: fn(T, U) -> bool) -> bool {
557 558
    let v0_len = len(v0);
    if v0_len != len(v1) { ret false; }
559
    let mut i = 0u;
560 561 562 563
    while i < v0_len { if !f(v0[i], v1[i]) { ret false; }; i += 1u; }
    ret true;
}

B
Brian Anderson 已提交
564
#[doc = "Return true if a vector contains an element with the given value"]
565
fn contains<T>(v: [const T], x: T) -> bool {
566
    for each(v) {|elt| if x == elt { ret true; } }
567 568 569
    ret false;
}

B
Brian Anderson 已提交
570
#[doc = "Returns the number of elements that are equal to a given value"]
571
fn count<T>(v: [const T], x: T) -> uint {
572
    let mut cnt = 0u;
573
    for each(v) {|elt| if x == elt { cnt += 1u; } }
574 575 576
    ret cnt;
}

B
Brian Anderson 已提交
577
#[doc = "
578
Search for the first element that matches a given predicate
579 580 581 582

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 已提交
583
"]
584
fn find<T: copy>(v: [const T], f: fn(T) -> bool) -> option<T> {
585
    find_between(v, 0u, len(v), f)
586 587
}

B
Brian Anderson 已提交
588
#[doc = "
589 590 591 592 593
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 已提交
594
"]
595
fn find_between<T: copy>(v: [const T], start: uint, end: uint,
596
                      f: fn(T) -> bool) -> option<T> {
597
    option::map(position_between(v, start, end, f)) { |i| v[i] }
598 599
}

B
Brian Anderson 已提交
600
#[doc = "
601 602 603 604 605
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 已提交
606
"]
607
fn rfind<T: copy>(v: [const T], f: fn(T) -> bool) -> option<T> {
608
    rfind_between(v, 0u, len(v), f)
609 610
}

B
Brian Anderson 已提交
611
#[doc = "
612 613 614 615 616
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 已提交
617
"]
618
fn rfind_between<T: copy>(v: [const T], start: uint, end: uint,
619
                       f: fn(T) -> bool) -> option<T> {
620
    option::map(rposition_between(v, start, end, f)) { |i| v[i] }
621 622
}

B
Brian Anderson 已提交
623
#[doc = "Find the first index containing a matching value"]
624
fn position_elem<T>(v: [const T], x: T) -> option<uint> {
625
    position(v) { |y| x == y }
626 627
}

B
Brian Anderson 已提交
628
#[doc = "
629 630 631 632 633
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 已提交
634
"]
635
fn position<T>(v: [const T], f: fn(T) -> bool) -> option<uint> {
636
    position_between(v, 0u, len(v), f)
637 638
}

B
Brian Anderson 已提交
639
#[doc = "
640 641 642 643 644
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 已提交
645
"]
646
fn position_between<T>(v: [const T], start: uint, end: uint,
647
                    f: fn(T) -> bool) -> option<uint> {
648 649
    assert start <= end;
    assert end <= len(v);
650
    let mut i = start;
651
    while i < end { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
652 653 654
    ret none;
}

B
Brian Anderson 已提交
655
#[doc = "Find the last index containing a matching value"]
656
fn rposition_elem<T>(v: [const T], x: T) -> option<uint> {
657 658 659
    rposition(v) { |y| x == y }
}

B
Brian Anderson 已提交
660
#[doc = "
661
Find the last index matching some predicate
662

663 664 665
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 已提交
666
"]
667
fn rposition<T>(v: [const T], f: fn(T) -> bool) -> option<uint> {
668
    rposition_between(v, 0u, len(v), f)
669 670
}

B
Brian Anderson 已提交
671
#[doc = "
672 673 674 675 676
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 已提交
677
"]
678
fn rposition_between<T>(v: [const T], start: uint, end: uint,
679
                     f: fn(T) -> bool) -> option<uint> {
680 681
    assert start <= end;
    assert end <= len(v);
682
    let mut i = end;
683 684 685 686
    while i > start {
        if f(v[i - 1u]) { ret some::<uint>(i - 1u); }
        i -= 1u;
    }
687 688 689 690 691 692 693
    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 已提交
694
#[doc = "
695 696 697 698 699 700
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 已提交
701
"]
702
fn unzip<T: copy, U: copy>(v: [const (T, U)]) -> ([T], [U]) {
703
    let mut as = [], bs = [];
704
    for each(v) {|p| let (a, b) = p; as += [a]; bs += [b]; }
705 706 707
    ret (as, bs);
}

B
Brian Anderson 已提交
708
#[doc = "
709 710 711 712
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 已提交
713
"]
714
fn zip<T: copy, U: copy>(v: [const T], u: [const U]) -> [(T, U)] {
715 716 717
    let mut zipped = [];
    let sz = len(v);
    let mut i = 0u;
718
    assert sz == len(u);
719 720 721 722
    while i < sz { zipped += [(v[i], u[i])]; i += 1u; }
    ret zipped;
}

B
Brian Anderson 已提交
723
#[doc = "
724 725
Swaps two elements in a vector

B
Brian Anderson 已提交
726 727 728 729 730 731
# Arguments

* v  The input vector
* a - The index of the first element
* b - The index of the second element
"]
G
Graydon Hoare 已提交
732
fn swap<T>(v: [mut T], a: uint, b: uint) {
733 734 735
    v[a] <-> v[b];
}

B
Brian Anderson 已提交
736
#[doc = "Reverse the order of elements in a vector, in place"]
G
Graydon Hoare 已提交
737
fn reverse<T>(v: [mut T]) {
738
    let mut i: uint = 0u;
739 740 741 742 743
    let ln = len::<T>(v);
    while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
}


B
Brian Anderson 已提交
744
#[doc = "Returns a vector with the order of elements reversed"]
745
fn reversed<T: copy>(v: [const T]) -> [T] {
746 747
    let mut rs: [T] = [];
    let mut i = len::<T>(v);
748 749 750 751 752 753
    if i == 0u { ret rs; } else { i -= 1u; }
    while i != 0u { rs += [v[i]]; i -= 1u; }
    rs += [v[0]];
    ret rs;
}

B
Brian Anderson 已提交
754
#[doc = "
755 756 757 758
Iterates over a vector

Iterates over vector `v` and, for each element, calls function `f` with the
element's value.
B
Brian Anderson 已提交
759
"]
760
#[inline(always)]
N
Niko Matsakis 已提交
761
fn iter<T>(v: [const T], f: fn(T)) {
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
    iter_between(v, 0u, vec::len(v), f)
}

/*
Function: iter_between

Iterates over a vector

Iterates over vector `v` and, for each element, calls function `f` with the
element's value.

*/
#[inline(always)]
fn iter_between<T>(v: [const T], start: uint, end: uint, f: fn(T)) {
    assert start <= end;
    assert end <= vec::len(v);
778
    unsafe {
779 780 781
        let mut n = end;
        let mut p = ptr::offset(unsafe::to_ptr(v), start);
        while n > start {
782 783 784 785 786
            f(*p);
            p = ptr::offset(p, 1u);
            n -= 1u;
        }
    }
787 788
}

789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
#[doc = "
Iterates over a vector, with option to break
"]
#[inline(always)]
fn each<T>(v: [const T], f: fn(T) -> bool) unsafe {
    let mut n = len(v);
    let mut p = ptr::offset(unsafe::to_ptr(v), 0u);
    while n > 0u {
        if !f(*p) { break; }
        p = ptr::offset(p, 1u);
        n -= 1u;
    }
}

#[doc = "
Iterates over a vector's elements and indices
"]
#[inline(always)]
fn eachi<T>(v: [const T], f: fn(uint, T) -> bool) unsafe {
    let mut i = 0u, l = len(v);
    let mut p = ptr::offset(unsafe::to_ptr(v), 0u);
810
    while i < l {
811 812 813 814 815 816
        if !f(i, *p) { break; }
        p = ptr::offset(p, 1u);
        i += 1u;
    }
}

817 818 819 820 821 822 823
#[doc = "
Iterates over two vectors simultaneously

# Failure

Both vectors must have the same length
"]
824
#[inline]
825 826 827 828 829
fn iter2<U, T>(v1: [const U], v2: [const T], f: fn(U, T)) {
    assert len(v1) == len(v2);
    uint::range(0u, len(v1)) {|i|
        f(v1[i], v2[i])
    }
830 831
}

B
Brian Anderson 已提交
832
#[doc = "
833 834 835 836
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 已提交
837
"]
838
#[inline(always)]
N
Niko Matsakis 已提交
839
fn iteri<T>(v: [const T], f: fn(uint, T)) {
840 841
    let mut i = 0u;
    let l = len(v);
842 843 844
    while i < l { f(i, v[i]); i += 1u; }
}

B
Brian Anderson 已提交
845
#[doc = "
846 847 848 849
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 已提交
850
"]
N
Niko Matsakis 已提交
851
fn riter<T>(v: [const T], f: fn(T)) {
852
    riteri(v) { |_i, v| f(v) }
853 854
}

B
Brian Anderson 已提交
855
#[doc ="
856 857 858 859
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 已提交
860
"]
N
Niko Matsakis 已提交
861
fn riteri<T>(v: [const T], f: fn(uint, T)) {
862
    let mut i = len(v);
863 864 865 866 867 868
    while 0u < i {
        i -= 1u;
        f(i, v[i]);
    };
}

B
Brian Anderson 已提交
869 870
#[doc = "
Iterate over all permutations of vector `v`.
871

B
Brian Anderson 已提交
872 873 874
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).
875 876 877

The total number of permutations produced is `len(v)!`.  If `v` contains
repeated elements, then some permutations are repeated.
B
Brian Anderson 已提交
878
"]
879
fn permute<T: copy>(v: [T], put: fn([T])) {
880 881 882 883
  let ln = len(v);
  if ln == 0u {
    put([]);
  } else {
884
    let mut i = 0u;
885 886 887 888 889 890 891 892 893
    while i < ln {
      let elt = v[i];
      let rest = slice(v, 0u, i) + slice(v, i+1u, ln);
      permute(rest) {|permutation| put([elt] + permutation)}
      i += 1u;
    }
  }
}

894
fn windowed <TT: copy> (nn: uint, xx: [const TT]) -> [[TT]] {
895
   let mut ww = [];
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910

   assert 1u <= nn;

   vec::iteri (xx, {|ii, _x|
      let len = vec::len(xx);

      if ii+nn <= len {
         let w = vec::slice ( xx, ii, ii+nn );
         vec::push (ww, w);
      }
   });

   ret ww;
}

B
Brian Anderson 已提交
911 912
#[doc = "
Work with the buffer of a vector.
913

B
Brian Anderson 已提交
914 915 916
Allows for unsafe manipulation of vector contents, which is useful for native
interop.
"]
917 918 919 920
fn as_buf<E,T>(v: [const E], f: fn(*E) -> T) -> T unsafe {
    let buf = unsafe::to_ptr(v); f(buf)
}

G
Graydon Hoare 已提交
921 922
fn as_mut_buf<E,T>(v: [mut E], f: fn(*mut E) -> T) -> T unsafe {
    let buf = unsafe::to_ptr(v) as *mut E; f(buf)
923 924
}

B
Brian Anderson 已提交
925
#[doc = "An extension implementation providing a `len` method"]
926
impl vec_len<T> for [const T] {
B
Brian Anderson 已提交
927
    #[doc = "Return the length of the vector"]
928
    #[inline(always)]
929 930
    fn len() -> uint { len(self) }
}
931

B
Brian Anderson 已提交
932
#[doc = "Unsafe operations"]
933
mod unsafe {
934
    // FIXME: This should have crate visibility
B
Brian Anderson 已提交
935
    #[doc = "The internal representation of a vector"]
G
Graydon Hoare 已提交
936
    type vec_repr = {mut fill: uint, mut alloc: uint, data: u8};
937

B
Brian Anderson 已提交
938
    #[doc = "
939 940
    Constructs a vector from an unsafe pointer to a buffer

B
Brian Anderson 已提交
941
    # Arguments
942

B
Brian Anderson 已提交
943 944 945
    * ptr - An unsafe pointer to a buffer of `T`
    * elts - The number of elements in the buffer
    "]
946
    #[inline(always)]
947 948 949 950 951
    unsafe fn from_buf<T>(ptr: *T, elts: uint) -> [T] {
        ret rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
                                        ptr, elts);
    }

B
Brian Anderson 已提交
952
    #[doc = "
953 954 955 956 957
    Sets the length of a vector

    This well 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.
B
Brian Anderson 已提交
958
    "]
959
    #[inline(always)]
960 961 962 963 964
    unsafe fn set_len<T>(&v: [const T], new_len: uint) {
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        (**repr).fill = new_len * sys::size_of::<T>();
    }

B
Brian Anderson 已提交
965
    #[doc = "
966 967 968 969 970 971 972
    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 已提交
973
    "]
974
    #[inline(always)]
975 976 977 978 979 980
    unsafe fn to_ptr<T>(v: [const T]) -> *T {
        let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
        ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
    }
}

B
Brian Anderson 已提交
981
#[doc = "Operations on `[u8]`"]
982 983 984 985 986
mod u8 {
    export cmp;
    export lt, le, eq, ne, ge, gt;
    export hash;

B
Brian Anderson 已提交
987
    #[doc = "Bytewise string comparison"]
988 989 990
    pure fn cmp(&&a: [u8], &&b: [u8]) -> int unsafe {
        let a_len = len(a);
        let b_len = len(b);
991
        let n = uint::min(a_len, b_len) as libc::size_t;
992 993
        let r = libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
                             unsafe::to_ptr(b) as *libc::c_void, n) as int;
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005

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

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

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

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

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

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

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

B
Brian Anderson 已提交
1024
    #[doc = "String hash function"]
1025 1026 1027 1028
    fn hash(&&s: [u8]) -> uint {
        // djb hash.
        // FIXME: replace with murmur.

1029
        let mut u: uint = 5381u;
1030 1031 1032 1033 1034
        vec::iter(s, { |c| u *= 33u; u += c as uint; });
        ret u;
    }
}

1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
#[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; }

1048
    fn square_if_odd(&&n: uint) -> option<uint> {
1049 1050 1051 1052 1053 1054 1055 1056 1057
        ret if n % 2u == 1u { some(n * n) } else { none };
    }

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

    #[test]
    fn test_unsafe_ptrs() unsafe {
        // Test on-stack copy-from-buf.
        let a = [1, 2, 3];
1058
        let mut ptr = unsafe::to_ptr(a);
1059 1060 1061 1062 1063 1064 1065 1066
        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.
        let c = [1, 2, 3, 4, 5];
1067
        ptr = unsafe::to_ptr(c);
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
        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);
    }

    #[test]
1078 1079
    fn test_from_fn() {
        // Test on-stack from_fn.
1080
        let mut v = from_fn(3u, square);
1081 1082 1083 1084 1085
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);

1086 1087
        // Test on-heap from_fn.
        v = from_fn(5u, square);
1088 1089 1090 1091 1092 1093 1094 1095 1096
        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]
1097 1098
    fn test_from_elem() {
        // Test on-stack from_elem.
1099
        let mut v = from_elem(2u, 10u);
1100 1101 1102 1103
        assert (len(v) == 2u);
        assert (v[0] == 10u);
        assert (v[1] == 10u);

1104 1105
        // Test on-heap from_elem.
        v = from_elem(6u, 20u);
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
        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() {
        assert (is_empty::<int>([]));
        assert (!is_empty([0]));
    }

    #[test]
    fn test_is_not_empty() {
        assert (is_not_empty([0]));
        assert (!is_not_empty::<int>([]));
    }

    #[test]
    fn test_head() {
        let a = [11, 12];
        assert (head(a) == 11);
    }

    #[test]
    fn test_tail() {
1134
        let mut a = [11];
1135 1136 1137 1138 1139 1140 1141 1142
        assert (tail(a) == []);

        a = [11, 12];
        assert (tail(a) == [12]);
    }

    #[test]
    fn test_last() {
1143
        let mut n = last_opt([]);
1144
        assert (n == none);
1145
        n = last_opt([1, 2, 3]);
1146
        assert (n == some(3));
1147
        n = last_opt([1, 2, 3, 4, 5]);
1148 1149 1150 1151 1152 1153
        assert (n == some(5));
    }

    #[test]
    fn test_slice() {
        // Test on-stack -> on-stack slice.
1154
        let mut v = slice([1, 2, 3], 1u, 3u);
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
        assert (len(v) == 2u);
        assert (v[0] == 2);
        assert (v[1] == 3);

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

        // Test on-heap -> on-heap slice.
        v = slice([1, 2, 3, 4, 5, 6], 1u, 6u);
        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.
1179 1180
        let mut v = [1, 2, 3];
        let mut e = pop(v);
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (e == 3);

        // Test on-heap pop.
        v = [1, 2, 3, 4, 5];
        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().
1200
        let mut v = [];
1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
        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().
1215
        let mut v = [];
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
        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() {
1233
        let mut v = [];
1234 1235 1236 1237 1238 1239 1240 1241 1242
        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() {
G
Graydon Hoare 已提交
1243
        let mut v = [mut 1, 2, 3];
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
        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.
1256 1257
        let mut v = [1u, 2u, 3u];
        let mut w = map(v, square_ref);
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);

        // Test on-heap map.
        v = [1u, 2u, 3u, 4u, 5u];
        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;
        let v0 = [1, 2, 3, 4, 5];
        let v1 = [5, 4, 3, 2, 1];
        let u = map2::<int, int, int>(v0, v1, f);
1281
        let mut i = 0;
1282 1283 1284 1285 1286 1287
        while i < 5 { assert (v0[i] * v1[i] == u[i]); i += 1; }
    }

    #[test]
    fn test_filter_map() {
        // Test on-stack filter-map.
1288 1289
        let mut v = [1u, 2u, 3u];
        let mut w = filter_map(v, square_if_odd);
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
        assert (len(w) == 2u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);

        // Test on-heap filter-map.
        v = [1u, 2u, 3u, 4u, 5u];
        w = filter_map(v, square_if_odd);
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);
        assert (w[2] == 25u);

1302
        fn halve(&&i: int) -> option<int> {
1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
            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; }
        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];
        assert (filter_map(all_even, halve) == map(all_even, halve_for_sure));
        assert (filter_map(all_odd1, halve) == []);
        assert (filter_map(all_odd2, halve) == []);
        assert (filter_map(mix, halve) == mix_dest);
    }

    #[test]
    fn test_filter() {
        assert filter([1u, 2u, 3u], is_odd) == [1u, 3u];
        assert filter([1u, 2u, 4u, 8u, 16u], is_three) == [];
    }

    #[test]
    fn test_foldl() {
        // Test on-stack fold.
1328 1329
        let mut v = [1u, 2u, 3u];
        let mut sum = foldl(0u, v, add);
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
        assert (sum == 6u);

        // Test on-heap fold.
        v = [1u, 2u, 3u, 4u, 5u];
        sum = foldl(0u, v, add);
        assert (sum == 15u);
    }

    #[test]
    fn test_foldl2() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1343
        let mut v = [1, 2, 3, 4];
1344 1345 1346 1347 1348 1349 1350 1351 1352
        let sum = foldl(0, v, sub);
        assert sum == -10;
    }

    #[test]
    fn test_foldr() {
        fn sub(&&a: int, &&b: int) -> int {
            a - b
        }
1353
        let mut v = [1, 2, 3, 4];
1354 1355 1356 1357 1358 1359
        let sum = foldr(v, 0, sub);
        assert sum == -2;
    }

    #[test]
    fn test_iter_empty() {
1360
        let mut i = 0;
1361 1362 1363 1364 1365 1366
        iter::<int>([], { |_v| i += 1 });
        assert i == 0;
    }

    #[test]
    fn test_iter_nonempty() {
1367
        let mut i = 0;
1368 1369 1370 1371 1372 1373
        iter([1, 2, 3], { |v| i += v });
        assert i == 6;
    }

    #[test]
    fn test_iteri() {
1374
        let mut i = 0;
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
        iteri([1, 2, 3], { |j, v|
            if i == 0 { assert v == 1; }
            assert j + 1u == v as uint;
            i += v;
        });
        assert i == 6;
    }

    #[test]
    fn test_riter_empty() {
1385
        let mut i = 0;
1386 1387 1388 1389 1390 1391
        riter::<int>([], { |_v| i += 1 });
        assert i == 0;
    }

    #[test]
    fn test_riter_nonempty() {
1392
        let mut i = 0;
1393 1394 1395 1396 1397 1398 1399 1400 1401
        riter([1, 2, 3], { |v|
            if i == 0 { assert v == 3; }
            i += v
        });
        assert i == 6;
    }

    #[test]
    fn test_riteri() {
1402
        let mut i = 0;
1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
        riteri([0, 1, 2], { |j, v|
            if i == 0 { assert v == 2; }
            assert j == v as uint;
            i += v;
        });
        assert i == 3;
    }

    #[test]
    fn test_permute() {
1413
        let mut results: [[int]];
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477

        results = [];
        permute([]) {|v| results += [v]; }
        assert results == [[]];

        results = [];
        permute([7]) {|v| results += [v]; }
        assert results == [[7]];

        results = [];
        permute([1,1]) {|v| results += [v]; }
        assert results == [[1,1],[1,1]];

        results = [];
        permute([5,2,0]) {|v| results += [v]; }
        assert results == [[5,2,0],[5,0,2],[2,5,0],[2,0,5],[0,5,2],[0,2,5]];
    }

    #[test]
    fn test_any_and_all() {
        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));

        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));
    }

    #[test]
    fn test_any2_and_all2() {

        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));

        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));
    }

    #[test]
    fn test_zip_unzip() {
        let v1 = [1, 2, 3];
        let v2 = [4, 5, 6];

        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]
1478 1479
    fn test_position_elem() {
        assert position_elem([], 1) == none;
1480 1481

        let v1 = [1, 2, 3, 3, 2, 5];
1482 1483 1484 1485
        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;
1486 1487 1488
    }

    #[test]
1489
    fn test_position() {
1490 1491
        fn less_than_three(&&i: int) -> bool { ret i < 3; }
        fn is_eighteen(&&i: int) -> bool { ret i == 18; }
1492 1493 1494 1495 1496 1497

        assert position([], less_than_three) == none;

        let v1 = [5, 4, 3, 2, 1];
        assert position(v1, less_than_three) == some(3u);
        assert position(v1, is_eighteen) == none;
1498 1499 1500
    }

    #[test]
1501 1502
    fn test_position_between() {
        assert position_between([], 0u, 0u, f) == none;
1503 1504

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

1507 1508 1509 1510 1511
        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);
1512

1513 1514 1515 1516
        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);
1517

1518 1519 1520
        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);
1521

1522 1523
        assert position_between(v, 3u, 3u, f) == none;
        assert position_between(v, 3u, 4u, f) == some(3u);
1524

1525
        assert position_between(v, 4u, 4u, f) == none;
1526 1527
    }

1528 1529 1530 1531 1532 1533
    #[test]
    fn test_find() {
        assert find([], f) == none;

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
1534
        let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
1535 1536 1537 1538 1539 1540

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

    #[test]
1541 1542
    fn test_find_between() {
        assert find_between([], 0u, 0u, f) == none;
1543 1544

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

1547 1548 1549 1550 1551
        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'));
1552

1553 1554 1555 1556
        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'));
1557

1558 1559 1560
        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'));
1561

1562 1563
        assert find_between(v, 3u, 3u, f) == none;
        assert find_between(v, 3u, 4u, f) == some((3, 'b'));
1564

1565
        assert find_between(v, 4u, 4u, f) == none;
1566 1567
    }

1568 1569 1570 1571 1572 1573
    #[test]
    fn test_rposition() {
        assert find([], f) == none;

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
1574
        let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
1575 1576 1577 1578 1579 1580

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

    #[test]
1581 1582
    fn test_rposition_between() {
        assert rposition_between([], 0u, 0u, f) == none;
1583 1584

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

1587 1588 1589 1590 1591
        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);
1592

1593 1594 1595 1596
        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);
1597

1598 1599 1600
        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);
1601

1602 1603
        assert rposition_between(v, 3u, 3u, f) == none;
        assert rposition_between(v, 3u, 4u, f) == some(3u);
1604

1605
        assert rposition_between(v, 4u, 4u, f) == none;
1606
    }
1607 1608 1609 1610 1611 1612 1613

    #[test]
    fn test_rfind() {
        assert rfind([], f) == none;

        fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
        fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' }
1614
        let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
1615 1616 1617 1618 1619 1620

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

    #[test]
1621 1622
    fn test_rfind_between() {
        assert rfind_between([], 0u, 0u, f) == none;
1623 1624

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

1627 1628 1629 1630 1631
        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'));
1632

1633 1634 1635 1636
        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'));
1637

1638 1639 1640
        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'));
1641

1642 1643
        assert rfind_between(v, 3u, 3u, f) == none;
        assert rfind_between(v, 3u, 4u, f) == some((3, 'b'));
1644

1645
        assert rfind_between(v, 4u, 4u, f) == none;
1646 1647 1648 1649
    }

    #[test]
    fn reverse_and_reversed() {
G
Graydon Hoare 已提交
1650
        let v: [mut int] = [mut 10, 20];
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
        assert (v[0] == 10);
        assert (v[1] == 20);
        reverse(v);
        assert (v[0] == 20);
        assert (v[1] == 10);
        let v2 = reversed::<int>([10, 20]);
        assert (v2[0] == 20);
        assert (v2[1] == 10);
        v[0] = 30;
        assert (v2[0] == 20);
        // Make sure they work with 0-length vectors too.

        let v4 = reversed::<int>([]);
        assert (v4 == []);
G
Graydon Hoare 已提交
1665
        let v3: [mut int] = [mut];
1666 1667 1668 1669 1670
        reverse::<int>(v3);
    }

    #[test]
    fn reversed_mut() {
G
Graydon Hoare 已提交
1671
        let v2 = reversed::<int>([mut 10, 20]);
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
        assert (v2[0] == 20);
        assert (v2[1] == 10);
    }

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

1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723
    #[test]
    fn test_split() {
        fn f(&&x: int) -> bool { x == 3 }

        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]];
    }

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

        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]];
    }

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

        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]];
    }

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

        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]];
    }

1724
    #[test]
B
Brian Anderson 已提交
1725
    #[should_fail]
1726 1727
    #[ignore(cfg(target_os = "win32"))]
    fn test_init_empty() {
B
Brian Anderson 已提交
1728
        init::<int>([]);
1729 1730 1731 1732 1733 1734 1735
    }

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

1736 1737 1738 1739 1740 1741 1742
    #[test]
    fn test_connect() {
        assert connect([], 0) == [];
        assert connect([[1], [2, 3]], 0) == [1, 0, 2, 3];
        assert connect([[1], [2], [3]], 0) == [1, 0, 2, 0, 3];
    }

1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
    #[test]
    fn test_windowed () {
        assert [[1u,2u,3u],[2u,3u,4u],[3u,4u,5u],[4u,5u,6u]]
              == windowed (3u, [1u,2u,3u,4u,5u,6u]);

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

        assert [] == windowed (7u, [1u,2u,3u,4u,5u,6u]);
    }

    #[test]
    #[should_fail]
1756
    #[ignore(cfg(target_os = "win32"))]
1757 1758 1759
    fn test_windowed_() {
        let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]);
    }
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777

    #[test]
    fn to_mut_no_copy() unsafe {
        let x = [1, 2, 3];
        let addr = unsafe::to_ptr(x);
        let x_mut = to_mut(x);
        let addr_mut = unsafe::to_ptr(x_mut);
        assert addr == addr_mut;
    }

    #[test]
    fn from_mut_no_copy() unsafe {
        let x = [mut 1, 2, 3];
        let addr = unsafe::to_ptr(x);
        let x_imm = from_mut(x);
        let addr_imm = unsafe::to_ptr(x_imm);
        assert addr == addr_imm;
    }
B
Brian Anderson 已提交
1778 1779 1780

    #[test]
    fn test_unshift() {
1781
        let mut x = [1, 2, 3];
B
Brian Anderson 已提交
1782 1783 1784
        unshift(x, 0);
        assert x == [0, 1, 2, 3];
    }
1785 1786
}

1787 1788 1789 1790 1791 1792 1793
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End: