slice.rs 52.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Slice management and manipulation
//!
//! For more details `std::slice`.

15
#![stable]
16 17
#![doc(primitive = "slice")]

B
Brian Anderson 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// How this module is organized.
//
// The library infrastructure for slices is fairly messy. There's
// a lot of stuff defined here. Let's keep it clean.
//
// Since slices don't support inherent methods; all operations
// on them are defined on traits, which are then reexported from
// the prelude for convenience. So there are a lot of traits here.
//
// The layout of this file is thus:
//
// * Slice-specific 'extension' traits and their implementations. This
//   is where most of the slice API resides.
// * Implementations of a few common traits with important slice ops.
// * Definitions of a bunch of iterators.
// * Free functions.
// * The `raw` and `bytes` submodules.
// * Boilerplate trait implementations.

A
Alex Crichton 已提交
37
use mem::transmute;
38
use clone::Clone;
39
use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv};
40 41 42
use cmp;
use default::Default;
use iter::*;
43
use num::{Int, div_rem};
N
Nick Cameron 已提交
44
use ops;
45 46 47 48 49
use option::{None, Option, Some};
use ptr;
use ptr::RawPtr;
use mem;
use mem::size_of;
J
Jorge Aparicio 已提交
50
use kinds::{Sized, marker};
B
Brian Anderson 已提交
51
use raw::Repr;
52
// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
53
use raw::Slice as RawSlice;
54

55

B
Brian Anderson 已提交
56 57 58 59
//
// Extension traits
//

60 61 62
/// Extension methods for slices.
#[unstable = "may merge with other traits"]
pub trait SlicePrelude<T> for Sized? {
63 64
    /// Returns a subslice spanning the interval [`start`, `end`).
    ///
65
    /// Panics when the end of the new slice lies beyond the end of the
66 67 68
    /// original slice (i.e. when `end > self.len()`) or when `start > end`.
    ///
    /// Slicing with `start` equal to `end` yields an empty slice.
69
    #[unstable = "waiting on final error conventions/slicing syntax"]
J
Jorge Aparicio 已提交
70
    fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
71 72 73

    /// Returns a subslice from `start` to the end of the slice.
    ///
74
    /// Panics when `start` is strictly greater than the length of the original slice.
75 76
    ///
    /// Slicing from `self.len()` yields an empty slice.
77
    #[unstable = "waiting on final error conventions/slicing syntax"]
J
Jorge Aparicio 已提交
78
    fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
79 80 81

    /// Returns a subslice from the start of the slice to `end`.
    ///
82
    /// Panics when `end` is strictly greater than the length of the original slice.
83 84
    ///
    /// Slicing to `0` yields an empty slice.
85
    #[unstable = "waiting on final error conventions/slicing syntax"]
J
Jorge Aparicio 已提交
86
    fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
87

88 89 90 91 92 93
    /// Divides one slice into two at an index.
    ///
    /// The first will contain all indices from `[0, mid)` (excluding
    /// the index `mid` itself) and the second will contain all
    /// indices from `[mid, len)` (excluding the index `len` itself).
    ///
94
    /// Panics if `mid > len`.
A
Aaron Turon 已提交
95
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
96
    fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
97

A
Aaron Turon 已提交
98
    /// Returns an iterator over the slice
99
    #[unstable = "iterator type may change"]
J
Jorge Aparicio 已提交
100
    fn iter<'a>(&'a self) -> Items<'a, T>;
A
Aaron Turon 已提交
101 102 103 104

    /// Returns an iterator over subslices separated by elements that match
    /// `pred`.  The matched element is not contained in the subslices.
    #[unstable = "iterator type may change, waiting on unboxed closures"]
J
Jorge Aparicio 已提交
105
    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
A
Aaron Turon 已提交
106 107 108 109

    /// Returns an iterator over subslices separated by elements that match
    /// `pred`, limited to splitting at most `n` times.  The matched element is
    /// not contained in the subslices.
110
    #[unstable = "iterator type may change"]
J
Jorge Aparicio 已提交
111
    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
A
Aaron Turon 已提交
112 113 114 115 116

    /// Returns an iterator over subslices separated by elements that match
    /// `pred` limited to splitting at most `n` times. This starts at the end of
    /// the slice and works backwards.  The matched element is not contained in
    /// the subslices.
117
    #[unstable = "iterator type may change"]
J
Jorge Aparicio 已提交
118
    fn rsplitn<'a>(&'a self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
B
Brian Anderson 已提交
119

A
Aaron Turon 已提交
120 121 122 123
    /// Returns an iterator over all contiguous windows of length
    /// `size`. The windows overlap. If the slice is shorter than
    /// `size`, the iterator returns no values.
    ///
124
    /// # Panics
A
Aaron Turon 已提交
125
    ///
126
    /// Panics if `size` is 0.
A
Aaron Turon 已提交
127 128 129 130 131 132 133 134 135 136 137 138
    ///
    /// # Example
    ///
    /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`,
    /// `[3,4]`):
    ///
    /// ```rust
    /// let v = &[1i, 2, 3, 4];
    /// for win in v.windows(2) {
    ///     println!("{}", win);
    /// }
    /// ```
139
    #[unstable = "iterator type may change"]
J
Jorge Aparicio 已提交
140
    fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
A
Aaron Turon 已提交
141 142 143 144 145 146

    /// Returns an iterator over `size` elements of the slice at a
    /// time. The chunks do not overlap. If `size` does not divide the
    /// length of the slice, then the last chunk will not have length
    /// `size`.
    ///
147
    /// # Panics
A
Aaron Turon 已提交
148
    ///
149
    /// Panics if `size` is 0.
A
Aaron Turon 已提交
150 151 152 153 154 155 156 157 158 159 160 161
    ///
    /// # Example
    ///
    /// Print the slice two elements at a time (i.e. `[1,2]`,
    /// `[3,4]`, `[5]`):
    ///
    /// ```rust
    /// let v = &[1i, 2, 3, 4, 5];
    /// for win in v.chunks(2) {
    ///     println!("{}", win);
    /// }
    /// ```
162
    #[unstable = "iterator type may change"]
J
Jorge Aparicio 已提交
163
    fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
B
Brian Anderson 已提交
164

A
Aaron Turon 已提交
165 166 167
    /// Returns the element of a slice at the given index, or `None` if the
    /// index is out of bounds.
    #[unstable = "waiting on final collection conventions"]
J
Jorge Aparicio 已提交
168
    fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
A
Aaron Turon 已提交
169 170

    /// Returns the first element of a slice, or `None` if it is empty.
171
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
172
    fn head<'a>(&'a self) -> Option<&'a T>;
A
Aaron Turon 已提交
173 174

    /// Returns all but the first element of a slice.
175
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
176
    fn tail<'a>(&'a self) -> &'a [T];
A
Aaron Turon 已提交
177 178

    /// Returns all but the last element of a slice.
179
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
180
    fn init<'a>(&'a self) -> &'a [T];
A
Aaron Turon 已提交
181 182

    /// Returns the last element of a slice, or `None` if it is empty.
183
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
184
    fn last<'a>(&'a self) -> Option<&'a T>;
B
Brian Anderson 已提交
185

186 187 188
    /// Returns a pointer to the element at the given index, without doing
    /// bounds checking.
    #[unstable]
J
Jorge Aparicio 已提交
189
    unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T;
190

A
Aaron Turon 已提交
191 192 193 194 195 196 197
    /// Returns an unsafe pointer to the slice's buffer
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// Modifying the slice may cause its buffer to be reallocated, which
    /// would also make any pointers to it invalid.
198
    #[unstable]
B
Brian Anderson 已提交
199 200
    fn as_ptr(&self) -> *const T;

A
Aaron Turon 已提交
201
    /// Binary search a sorted slice with a comparator function.
B
Brian Anderson 已提交
202 203
    ///
    /// The comparator function should implement an order consistent
A
Aaron Turon 已提交
204
    /// with the sort order of the underlying slice, returning an
B
Brian Anderson 已提交
205 206 207
    /// order code that indicates whether its argument is `Less`,
    /// `Equal` or `Greater` the desired target.
    ///
208 209
    /// If a matching value is found then returns `Found`, containing
    /// the index for the matched element; if no match is found then
B
Brian Anderson 已提交
210 211
    /// `NotFound` is returned, containing the index where a matching
    /// element could be inserted while maintaining sorted order.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    ///
    /// # Example
    ///
    /// Looks up a series of four elements. The first is found, with a
    /// uniquely determined position; the second and third are not
    /// found; the fourth could match any position in `[1,4]`.
    ///
    /// ```rust
    /// use std::slice::{Found, NotFound};
    /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
    /// let s = s.as_slice();
    ///
    /// let seek = 13;
    /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), Found(9));
    /// let seek = 4;
    /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(7));
    /// let seek = 100;
    /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(13));
    /// let seek = 1;
    /// let r = s.binary_search(|probe| probe.cmp(&seek));
    /// assert!(match r { Found(1...4) => true, _ => false, });
    /// ```
A
Aaron Turon 已提交
234
    #[unstable = "waiting on unboxed closures"]
235
    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult;
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258

    /// Return the number of elements in the slice
    ///
    /// # Example
    ///
    /// ```
    /// let a = [1i, 2, 3];
    /// assert_eq!(a.len(), 3);
    /// ```
    #[experimental = "not triaged yet"]
    fn len(&self) -> uint;

    /// Returns true if the slice has a length of 0
    ///
    /// # Example
    ///
    /// ```
    /// let a = [1i, 2, 3];
    /// assert!(!a.is_empty());
    /// ```
    #[inline]
    #[experimental = "not triaged yet"]
    fn is_empty(&self) -> bool { self.len() == 0 }
B
Brian Anderson 已提交
259 260
    /// Returns a mutable reference to the element at the given index,
    /// or `None` if the index is out of bounds
A
Aaron Turon 已提交
261
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
262
    fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
263

B
Brian Anderson 已提交
264 265
    /// Work with `self` as a mut slice.
    /// Primarily intended for getting a &mut [T] from a [T, ..N].
J
Jorge Aparicio 已提交
266
    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
267

268 269
    /// Returns a mutable subslice spanning the interval [`start`, `end`).
    ///
270
    /// Panics when the end of the new slice lies beyond the end of the
271 272 273 274
    /// original slice (i.e. when `end > self.len()`) or when `start > end`.
    ///
    /// Slicing with `start` equal to `end` yields an empty slice.
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
275
    fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
276 277 278

    /// Returns a mutable subslice from `start` to the end of the slice.
    ///
279
    /// Panics when `start` is strictly greater than the length of the original slice.
280 281 282
    ///
    /// Slicing from `self.len()` yields an empty slice.
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
283
    fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
284 285 286

    /// Returns a mutable subslice from the start of the slice to `end`.
    ///
287
    /// Panics when `end` is strictly greater than the length of the original slice.
288 289 290
    ///
    /// Slicing to `0` yields an empty slice.
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
291
    fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
292

B
Brian Anderson 已提交
293
    /// Returns an iterator that allows modifying each value
A
Aaron Turon 已提交
294
    #[unstable = "waiting on iterator type name conventions"]
J
Jorge Aparicio 已提交
295
    fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T>;
A
Aaron Turon 已提交
296

A
Aaron Turon 已提交
297 298
    /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
299
    fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>;
A
Aaron Turon 已提交
300 301 302

    /// Returns all but the first element of a mutable slice
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
303
    fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
A
Aaron Turon 已提交
304 305 306

    /// Returns all but the last element of a mutable slice
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
307
    fn init_mut<'a>(&'a mut self) -> &'a mut [T];
A
Aaron Turon 已提交
308 309 310

    /// Returns a mutable pointer to the last item in the slice.
    #[unstable = "name may change"]
J
Jorge Aparicio 已提交
311
    fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
A
Aaron Turon 已提交
312

A
Aaron Turon 已提交
313 314 315
    /// Returns an iterator over mutable subslices separated by elements that
    /// match `pred`.  The matched element is not contained in the subslices.
    #[unstable = "waiting on unboxed closures, iterator type name conventions"]
J
Jorge Aparicio 已提交
316
    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
A
Aaron Turon 已提交
317

A
Aaron Turon 已提交
318 319 320 321
    /// Returns an iterator over subslices separated by elements that match
    /// `pred`, limited to splitting at most `n` times.  The matched element is
    /// not contained in the subslices.
    #[unstable = "waiting on unboxed closures, iterator type name conventions"]
J
Jorge Aparicio 已提交
322
    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
A
Aaron Turon 已提交
323 324 325 326 327 328

    /// Returns an iterator over subslices separated by elements that match
    /// `pred` limited to splitting at most `n` times. This starts at the end of
    /// the slice and works backwards.  The matched element is not contained in
    /// the subslices.
    #[unstable = "waiting on unboxed closures, iterator type name conventions"]
J
Jorge Aparicio 已提交
329
    fn rsplitn_mut<'a>(&'a mut self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
A
Aaron Turon 已提交
330 331 332 333 334 335

    /// Returns an iterator over `chunk_size` elements of the slice at a time.
    /// The chunks are mutable and do not overlap. If `chunk_size` does
    /// not divide the length of the slice, then the last chunk will not
    /// have length `chunk_size`.
    ///
336
    /// # Panics
A
Aaron Turon 已提交
337
    ///
338
    /// Panics if `chunk_size` is 0.
A
Aaron Turon 已提交
339
    #[unstable = "waiting on iterator type name conventions"]
J
Jorge Aparicio 已提交
340
    fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>;
341

A
Aaron Turon 已提交
342
    /// Swaps two elements in a slice.
B
Brian Anderson 已提交
343
    ///
344
    /// Panics if `a` or `b` are out of bounds.
B
Brian Anderson 已提交
345 346 347 348 349 350 351 352 353 354 355 356 357
    ///
    /// # Arguments
    ///
    /// * a - The index of the first element
    /// * b - The index of the second element
    ///
    /// # Example
    ///
    /// ```rust
    /// let mut v = ["a", "b", "c", "d"];
    /// v.swap(1, 3);
    /// assert!(v == ["a", "d", "c", "b"]);
    /// ```
A
Aaron Turon 已提交
358
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
359
    fn swap(&mut self, a: uint, b: uint);
360

B
Brian Anderson 已提交
361 362 363 364 365 366
    /// Divides one `&mut` into two at an index.
    ///
    /// The first will contain all indices from `[0, mid)` (excluding
    /// the index `mid` itself) and the second will contain all
    /// indices from `[mid, len)` (excluding the index `len` itself).
    ///
367
    /// Panics if `mid > len`.
B
Brian Anderson 已提交
368 369 370 371 372 373 374 375
    ///
    /// # Example
    ///
    /// ```rust
    /// let mut v = [1i, 2, 3, 4, 5, 6];
    ///
    /// // scoped to restrict the lifetime of the borrows
    /// {
A
Aaron Turon 已提交
376
    ///    let (left, right) = v.split_at_mut(0);
B
Brian Anderson 已提交
377 378 379 380 381
    ///    assert!(left == &mut []);
    ///    assert!(right == &mut [1i, 2, 3, 4, 5, 6]);
    /// }
    ///
    /// {
A
Aaron Turon 已提交
382
    ///     let (left, right) = v.split_at_mut(2);
B
Brian Anderson 已提交
383 384 385 386 387
    ///     assert!(left == &mut [1i, 2]);
    ///     assert!(right == &mut [3i, 4, 5, 6]);
    /// }
    ///
    /// {
A
Aaron Turon 已提交
388
    ///     let (left, right) = v.split_at_mut(6);
B
Brian Anderson 已提交
389 390 391 392
    ///     assert!(left == &mut [1i, 2, 3, 4, 5, 6]);
    ///     assert!(right == &mut []);
    /// }
    /// ```
A
Aaron Turon 已提交
393
    #[unstable = "waiting on final error conventions"]
J
Jorge Aparicio 已提交
394
    fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
395

A
Aaron Turon 已提交
396
    /// Reverse the order of elements in a slice, in place.
B
Brian Anderson 已提交
397 398 399 400 401 402 403 404
    ///
    /// # Example
    ///
    /// ```rust
    /// let mut v = [1i, 2, 3];
    /// v.reverse();
    /// assert!(v == [3i, 2, 1]);
    /// ```
A
Aaron Turon 已提交
405
    #[experimental = "may be moved to iterators instead"]
J
Jorge Aparicio 已提交
406
    fn reverse(&mut self);
407

B
Brian Anderson 已提交
408
    /// Returns an unsafe mutable pointer to the element in index
A
Aaron Turon 已提交
409
    #[experimental = "waiting on unsafe conventions"]
J
Jorge Aparicio 已提交
410
    unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
411

A
Aaron Turon 已提交
412
    /// Return an unsafe mutable pointer to the slice's buffer.
B
Brian Anderson 已提交
413
    ///
A
Aaron Turon 已提交
414
    /// The caller must ensure that the slice outlives the pointer this
B
Brian Anderson 已提交
415 416
    /// function returns, or else it will end up pointing to garbage.
    ///
A
Aaron Turon 已提交
417
    /// Modifying the slice may cause its buffer to be reallocated, which
B
Brian Anderson 已提交
418
    /// would also make any pointers to it invalid.
419
    #[inline]
A
Aaron Turon 已提交
420
    #[unstable]
J
Jorge Aparicio 已提交
421
    fn as_mut_ptr(&mut self) -> *mut T;
B
Brian Anderson 已提交
422
}
423

424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
#[unstable]
impl<T> SlicePrelude<T> for [T] {
    #[inline]
    fn slice(&self, start: uint, end: uint) -> &[T] {
        assert!(start <= end);
        assert!(end <= self.len());
        unsafe {
            transmute(RawSlice {
                data: self.as_ptr().offset(start as int),
                len: (end - start)
            })
        }
    }

    #[inline]
    fn slice_from(&self, start: uint) -> &[T] {
        self.slice(start, self.len())
    }

    #[inline]
    fn slice_to(&self, end: uint) -> &[T] {
        self.slice(0, end)
    }

    #[inline]
    fn split_at(&self, mid: uint) -> (&[T], &[T]) {
        (self[..mid], self[mid..])
    }

    #[inline]
    fn iter<'a>(&'a self) -> Items<'a, T> {
        unsafe {
            let p = self.as_ptr();
            if mem::size_of::<T>() == 0 {
                Items{ptr: p,
                      end: (p as uint + self.len()) as *const T,
                      marker: marker::ContravariantLifetime::<'a>}
            } else {
                Items{ptr: p,
                      end: p.offset(self.len() as int),
                      marker: marker::ContravariantLifetime::<'a>}
            }
        }
    }

    #[inline]
    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
        Splits {
            v: self,
            pred: pred,
            finished: false
        }
    }

    #[inline]
    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
        SplitsN {
            iter: self.split(pred),
            count: n,
            invert: false
        }
    }

    #[inline]
    fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
        SplitsN {
            iter: self.split(pred),
            count: n,
            invert: true
        }
    }

    #[inline]
    fn windows(&self, size: uint) -> Windows<T> {
        assert!(size != 0);
        Windows { v: self, size: size }
    }

    #[inline]
    fn chunks(&self, size: uint) -> Chunks<T> {
        assert!(size != 0);
        Chunks { v: self, size: size }
    }

    #[inline]
    fn get(&self, index: uint) -> Option<&T> {
        if index < self.len() { Some(&self[index]) } else { None }
    }

    #[inline]
    fn head(&self) -> Option<&T> {
        if self.len() == 0 { None } else { Some(&self[0]) }
    }

    #[inline]
    fn tail(&self) -> &[T] { self[1..] }

    #[inline]
    fn init(&self) -> &[T] {
        self[..self.len() - 1]
    }

    #[inline]
    fn last(&self) -> Option<&T> {
        if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
    }

    #[inline]
    unsafe fn unsafe_get(&self, index: uint) -> &T {
        transmute(self.repr().data.offset(index as int))
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        self.repr().data
    }

    #[unstable]
    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult {
        let mut base : uint = 0;
        let mut lim : uint = self.len();

        while lim != 0 {
            let ix = base + (lim >> 1);
            match f(&self[ix]) {
                Equal => return Found(ix),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => ()
            }
            lim >>= 1;
        }
        return NotFound(base);
    }

    #[inline]
    fn len(&self) -> uint { self.repr().len }

564
    #[inline]
J
Jorge Aparicio 已提交
565
    fn get_mut(&mut self, index: uint) -> Option<&mut T> {
B
Brian Anderson 已提交
566
        if index < self.len() { Some(&mut self[index]) } else { None }
567 568 569
    }

    #[inline]
J
Jorge Aparicio 已提交
570
    fn as_mut_slice(&mut self) -> &mut [T] { self }
571

J
Jorge Aparicio 已提交
572
    fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
573
        self[mut start..end]
574 575 576
    }

    #[inline]
J
Jorge Aparicio 已提交
577
    fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
578
        self[mut start..]
579 580 581
    }

    #[inline]
J
Jorge Aparicio 已提交
582
    fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
583
        self[mut ..end]
584 585
    }

586
    #[inline]
J
Jorge Aparicio 已提交
587
    fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
B
Brian Anderson 已提交
588
        unsafe {
J
Jorge Aparicio 已提交
589
            let self2: &mut [T] = mem::transmute_copy(&self);
590
            (self[mut ..mid], self2[mut mid..])
B
Brian Anderson 已提交
591
        }
592 593 594
    }

    #[inline]
J
Jorge Aparicio 已提交
595
    fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
B
Brian Anderson 已提交
596 597 598 599 600 601 602 603 604 605 606 607 608 609
        unsafe {
            let p = self.as_mut_ptr();
            if mem::size_of::<T>() == 0 {
                MutItems{ptr: p,
                         end: (p as uint + self.len()) as *mut T,
                         marker: marker::ContravariantLifetime::<'a>,
                         marker2: marker::NoCopy}
            } else {
                MutItems{ptr: p,
                         end: p.offset(self.len() as int),
                         marker: marker::ContravariantLifetime::<'a>,
                         marker2: marker::NoCopy}
            }
        }
610 611 612
    }

    #[inline]
J
Jorge Aparicio 已提交
613
    fn last_mut(&mut self) -> Option<&mut T> {
B
Brian Anderson 已提交
614 615 616
        let len = self.len();
        if len == 0 { return None; }
        Some(&mut self[len - 1])
617 618
    }

A
Aaron Turon 已提交
619
    #[inline]
J
Jorge Aparicio 已提交
620
    fn head_mut(&mut self) -> Option<&mut T> {
A
Aaron Turon 已提交
621 622 623 624
        if self.len() == 0 { None } else { Some(&mut self[0]) }
    }

    #[inline]
J
Jorge Aparicio 已提交
625
    fn tail_mut(&mut self) -> &mut [T] {
A
Aaron Turon 已提交
626
        let len = self.len();
627
        self[mut 1..len]
A
Aaron Turon 已提交
628 629 630
    }

    #[inline]
J
Jorge Aparicio 已提交
631
    fn init_mut(&mut self) -> &mut [T] {
A
Aaron Turon 已提交
632
        let len = self.len();
633
        self[mut 0..len - 1]
A
Aaron Turon 已提交
634 635
    }

636
    #[inline]
J
Jorge Aparicio 已提交
637
    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
B
Brian Anderson 已提交
638
        MutSplits { v: self, pred: pred, finished: false }
639 640
    }

A
Aaron Turon 已提交
641
    #[inline]
J
Jorge Aparicio 已提交
642
    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
A
Aaron Turon 已提交
643 644 645 646 647 648 649 650
        SplitsN {
            iter: self.split_mut(pred),
            count: n,
            invert: false
        }
    }

    #[inline]
J
Jorge Aparicio 已提交
651
    fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
A
Aaron Turon 已提交
652 653 654 655 656 657 658
        SplitsN {
            iter: self.split_mut(pred),
            count: n,
            invert: true
        }
   }

B
Brian Anderson 已提交
659
    #[inline]
J
Jorge Aparicio 已提交
660
    fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks<T> {
B
Brian Anderson 已提交
661 662
        assert!(chunk_size > 0);
        MutChunks { v: self, chunk_size: chunk_size }
663 664
    }

J
Jorge Aparicio 已提交
665
    fn swap(&mut self, a: uint, b: uint) {
B
Brian Anderson 已提交
666 667 668 669 670 671 672 673 674
        unsafe {
            // Can't take two mutable loans from one vector, so instead just cast
            // them to their raw pointers to do the swap
            let pa: *mut T = &mut self[a];
            let pb: *mut T = &mut self[b];
            ptr::swap(pa, pb);
        }
    }

J
Jorge Aparicio 已提交
675
    fn reverse(&mut self) {
B
Brian Anderson 已提交
676 677 678
        let mut i: uint = 0;
        let ln = self.len();
        while i < ln / 2 {
B
Brian Anderson 已提交
679 680
            // Unsafe swap to avoid the bounds check in safe swap.
            unsafe {
A
Aaron Turon 已提交
681 682
                let pa: *mut T = self.unsafe_mut(i);
                let pb: *mut T = self.unsafe_mut(ln - i - 1);
B
Brian Anderson 已提交
683 684
                ptr::swap(pa, pb);
            }
B
Brian Anderson 已提交
685 686 687 688 689
            i += 1;
        }
    }

    #[inline]
J
Jorge Aparicio 已提交
690
    unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T {
B
Brian Anderson 已提交
691 692 693 694
        transmute((self.repr().data as *mut T).offset(index as int))
    }

    #[inline]
J
Jorge Aparicio 已提交
695
    fn as_mut_ptr(&mut self) -> *mut T {
B
Brian Anderson 已提交
696 697
        self.repr().data as *mut T
    }
698 699
}

J
Jorge Aparicio 已提交
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
impl<T> ops::Index<uint, T> for [T] {
    fn index(&self, &index: &uint) -> &T {
        assert!(index < self.len());

        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
    }
}

impl<T> ops::IndexMut<uint, T> for [T] {
    fn index_mut(&mut self, &index: &uint) -> &mut T {
        assert!(index < self.len());

        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
    }
}

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
impl<T> ops::Slice<uint, [T]> for [T] {
    #[inline]
    fn as_slice_<'a>(&'a self) -> &'a [T] {
        self
    }

    #[inline]
    fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
        self.slice_or_fail(start, &self.len())
    }

    #[inline]
    fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
        self.slice_or_fail(&0, end)
    }
    #[inline]
    fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
        assert!(*start <= *end);
        assert!(*end <= self.len());
        unsafe {
            transmute(RawSlice {
                    data: self.as_ptr().offset(*start as int),
                    len: (*end - *start)
                })
        }
    }
}

impl<T> ops::SliceMut<uint, [T]> for [T] {
    #[inline]
    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
        self
    }

    #[inline]
    fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
        let len = &self.len();
        self.slice_or_fail_mut(start, len)
    }

    #[inline]
    fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
        self.slice_or_fail_mut(&0, end)
    }
    #[inline]
    fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
        assert!(*start <= *end);
        assert!(*end <= self.len());
        unsafe {
            transmute(RawSlice {
                    data: self.as_ptr().offset(*start as int),
                    len: (*end - *start)
                })
        }
    }
}

A
Aaron Turon 已提交
773
/// Extension methods for slices containing `PartialEq` elements.
774
#[unstable = "may merge with other traits"]
775
pub trait PartialEqSlicePrelude<T: PartialEq> for Sized? {
A
Aaron Turon 已提交
776
    /// Find the first index containing a matching value.
777 778
    fn position_elem(&self, t: &T) -> Option<uint>;

A
Aaron Turon 已提交
779
    /// Find the last index containing a matching value.
780 781
    fn rposition_elem(&self, t: &T) -> Option<uint>;

A
Aaron Turon 已提交
782
    /// Return true if the slice contains an element with the given value.
783 784
    fn contains(&self, x: &T) -> bool;

A
Aaron Turon 已提交
785
    /// Returns true if `needle` is a prefix of the slice.
786 787
    fn starts_with(&self, needle: &[T]) -> bool;

A
Aaron Turon 已提交
788
    /// Returns true if `needle` is a suffix of the slice.
789 790 791
    fn ends_with(&self, needle: &[T]) -> bool;
}

792
#[unstable = "trait is unstable"]
793
impl<T: PartialEq> PartialEqSlicePrelude<T> for [T] {
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
    #[inline]
    fn position_elem(&self, x: &T) -> Option<uint> {
        self.iter().position(|y| *x == *y)
    }

    #[inline]
    fn rposition_elem(&self, t: &T) -> Option<uint> {
        self.iter().rposition(|x| *x == *t)
    }

    #[inline]
    fn contains(&self, x: &T) -> bool {
        self.iter().any(|elt| *x == *elt)
    }

    #[inline]
    fn starts_with(&self, needle: &[T]) -> bool {
        let n = needle.len();
J
Jorge Aparicio 已提交
812
        self.len() >= n && needle == self[..n]
813 814 815 816 817
    }

    #[inline]
    fn ends_with(&self, needle: &[T]) -> bool {
        let (m, n) = (self.len(), needle.len());
J
Jorge Aparicio 已提交
818
        m >= n && needle == self[m-n..]
819 820 821
    }
}

A
Aaron Turon 已提交
822
/// Extension methods for slices containing `Ord` elements.
823
#[unstable = "may merge with other traits"]
824
pub trait OrdSlicePrelude<T: Ord> for Sized? {
A
Aaron Turon 已提交
825 826 827 828 829 830
    /// Binary search a sorted slice for a given element.
    ///
    /// If the value is found then `Found` is returned, containing the
    /// index of the matching element; if the value is not found then
    /// `NotFound` is returned, containing the index where a matching
    /// element could be inserted while maintaining sorted order.
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
    ///
    /// # Example
    ///
    /// Looks up a series of four elements. The first is found, with a
    /// uniquely determined position; the second and third are not
    /// found; the fourth could match any position in `[1,4]`.
    ///
    /// ```rust
    /// use std::slice::{Found, NotFound};
    /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
    /// let s = s.as_slice();
    ///
    /// assert_eq!(s.binary_search_elem(&13),  Found(9));
    /// assert_eq!(s.binary_search_elem(&4),   NotFound(7));
    /// assert_eq!(s.binary_search_elem(&100), NotFound(13));
    /// let r = s.binary_search_elem(&1);
    /// assert!(match r { Found(1...4) => true, _ => false, });
    /// ```
A
Aaron Turon 已提交
849
    #[unstable = "name likely to change"]
850
    fn binary_search_elem(&self, x: &T) -> BinarySearchResult;
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888

    /// Mutates the slice to the next lexicographic permutation.
    ///
    /// Returns `true` if successful and `false` if the slice is at the
    /// last-ordered permutation.
    ///
    /// # Example
    ///
    /// ```rust
    /// let v: &mut [_] = &mut [0i, 1, 2];
    /// v.next_permutation();
    /// let b: &mut [_] = &mut [0i, 2, 1];
    /// assert!(v == b);
    /// v.next_permutation();
    /// let b: &mut [_] = &mut [1i, 0, 2];
    /// assert!(v == b);
    /// ```
    #[experimental]
    fn next_permutation(&mut self) -> bool;

    /// Mutates the slice to the previous lexicographic permutation.
    ///
    /// Returns `true` if successful and `false` if the slice is at the
    /// first-ordered permutation.
    ///
    /// # Example
    ///
    /// ```rust
    /// let v: &mut [_] = &mut [1i, 0, 2];
    /// v.prev_permutation();
    /// let b: &mut [_] = &mut [0i, 2, 1];
    /// assert!(v == b);
    /// v.prev_permutation();
    /// let b: &mut [_] = &mut [0i, 1, 2];
    /// assert!(v == b);
    /// ```
    #[experimental]
    fn prev_permutation(&mut self) -> bool;
889 890
}

891
#[unstable = "trait is unstable"]
892
impl<T: Ord> OrdSlicePrelude<T> for [T] {
893 894 895 896
    #[unstable]
    fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
        self.binary_search(|p| p.cmp(x))
    }
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958

    #[experimental]
    fn next_permutation(&mut self) -> bool {
        // These cases only have 1 permutation each, so we can't do anything.
        if self.len() < 2 { return false; }

        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
        let mut i = self.len() - 1;
        while i > 0 && self[i-1] >= self[i] {
            i -= 1;
        }

        // If that is the entire vector, this is the last-ordered permutation.
        if i == 0 {
            return false;
        }

        // Step 2: Find the rightmost element larger than the pivot (i-1)
        let mut j = self.len() - 1;
        while j >= i && self[j] <= self[i-1]  {
            j -= 1;
        }

        // Step 3: Swap that element with the pivot
        self.swap(j, i-1);

        // Step 4: Reverse the (previously) weakly decreasing part
        self[mut i..].reverse();

        true
    }

    #[experimental]
    fn prev_permutation(&mut self) -> bool {
        // These cases only have 1 permutation each, so we can't do anything.
        if self.len() < 2 { return false; }

        // Step 1: Identify the longest, rightmost weakly increasing part of the vector
        let mut i = self.len() - 1;
        while i > 0 && self[i-1] <= self[i] {
            i -= 1;
        }

        // If that is the entire vector, this is the first-ordered permutation.
        if i == 0 {
            return false;
        }

        // Step 2: Reverse the weakly increasing part
        self[mut i..].reverse();

        // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
        let mut j = self.len() - 1;
        while j >= i && self[j-1] < self[i-1]  {
            j -= 1;
        }

        // Step 4: Swap that element with the pivot
        self.swap(i-1, j);

        true
    }
959 960
}

961
/// Extension methods for slices on Clone elements
962
#[unstable = "may merge with other traits"]
963
pub trait CloneSlicePrelude<T> for Sized? {
B
Brian Anderson 已提交
964 965 966
    /// Copies as many elements from `src` as it can into `self` (the
    /// shorter of `self.len()` and `src.len()`). Returns the number
    /// of elements copied.
967 968 969 970
    ///
    /// # Example
    ///
    /// ```rust
971
    /// use std::slice::CloneSlicePrelude;
972
    ///
B
Brian Anderson 已提交
973 974
    /// let mut dst = [0i, 0, 0];
    /// let src = [1i, 2];
975
    ///
976
    /// assert!(dst.clone_from_slice(src) == 2);
B
Brian Anderson 已提交
977
    /// assert!(dst == [1, 2, 0]);
978
    ///
B
Brian Anderson 已提交
979
    /// let src2 = [3i, 4, 5, 6];
980
    /// assert!(dst.clone_from_slice(src2) == 3);
B
Brian Anderson 已提交
981
    /// assert!(dst == [3i, 4, 5]);
982
    /// ```
J
Jorge Aparicio 已提交
983
    fn clone_from_slice(&mut self, &[T]) -> uint;
B
Brian Anderson 已提交
984
}
985

986
#[unstable = "trait is unstable"]
987
impl<T: Clone> CloneSlicePrelude<T> for [T] {
B
Brian Anderson 已提交
988
    #[inline]
J
Jorge Aparicio 已提交
989
    fn clone_from_slice(&mut self, src: &[T]) -> uint {
J
Julian Orth 已提交
990 991 992 993 994
        let min = cmp::min(self.len(), src.len());
        let dst = self.slice_to_mut(min);
        let src = src.slice_to(min);
        for i in range(0, min) {
            dst[i].clone_from(&src[i]);
B
Brian Anderson 已提交
995
        }
J
Julian Orth 已提交
996
        min
B
Brian Anderson 已提交
997 998
    }
}
999 1000 1001 1002




B
Brian Anderson 已提交
1003 1004 1005
//
// Common traits
//
1006

A
Aaron Turon 已提交
1007
/// Data that is viewable as a slice.
1008
#[unstable = "may merge with other traits"]
N
Nick Cameron 已提交
1009
pub trait AsSlice<T> {
B
Brian Anderson 已提交
1010 1011
    /// Work with `self` as a slice.
    fn as_slice<'a>(&'a self) -> &'a [T];
1012 1013
}

1014
#[unstable = "trait is unstable"]
N
Nick Cameron 已提交
1015
impl<'a,T> AsSlice<T> for &'a [T] {
B
Brian Anderson 已提交
1016 1017 1018 1019
    #[inline(always)]
    fn as_slice<'a>(&'a self) -> &'a [T] { *self }
}

1020
#[unstable = "waiting for DST"]
B
Brian Anderson 已提交
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
impl<'a, T> Default for &'a [T] {
    fn default() -> &'a [T] { &[] }
}

//
// Iterators
//

// The shared definition of the `Item` and `MutItems` iterators
macro_rules! iterator {
    (struct $name:ident -> $ptr:ty, $elem:ty) => {
1032
        #[experimental = "needs review"]
B
Brian Anderson 已提交
1033 1034 1035 1036 1037 1038 1039 1040
        impl<'a, T> Iterator<$elem> for $name<'a, T> {
            #[inline]
            fn next(&mut self) -> Option<$elem> {
                // could be implemented with slices, but this avoids bounds checks
                unsafe {
                    if self.ptr == self.end {
                        None
                    } else {
1041
                        if mem::size_of::<T>() == 0 {
B
Brian Anderson 已提交
1042 1043 1044
                            // purposefully don't use 'ptr.offset' because for
                            // vectors with 0-size elements this would return the
                            // same pointer.
1045 1046 1047 1048
                            self.ptr = transmute(self.ptr as uint + 1);

                            // Use a non-null pointer value
                            Some(transmute(1u))
B
Brian Anderson 已提交
1049
                        } else {
1050 1051
                            let old = self.ptr;
                            self.ptr = self.ptr.offset(1);
B
Brian Anderson 已提交
1052

1053 1054
                            Some(transmute(old))
                        }
B
Brian Anderson 已提交
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
                    }
                }
            }

            #[inline]
            fn size_hint(&self) -> (uint, Option<uint>) {
                let diff = (self.end as uint) - (self.ptr as uint);
                let size = mem::size_of::<T>();
                let exact = diff / (if size == 0 {1} else {size});
                (exact, Some(exact))
            }
        }

1068
        #[experimental = "needs review"]
B
Brian Anderson 已提交
1069 1070 1071 1072 1073 1074 1075 1076
        impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
            #[inline]
            fn next_back(&mut self) -> Option<$elem> {
                // could be implemented with slices, but this avoids bounds checks
                unsafe {
                    if self.end == self.ptr {
                        None
                    } else {
1077
                        if mem::size_of::<T>() == 0 {
B
Brian Anderson 已提交
1078
                            // See above for why 'ptr.offset' isn't used
1079 1080 1081 1082
                            self.end = transmute(self.end as uint - 1);

                            // Use a non-null pointer value
                            Some(transmute(1u))
B
Brian Anderson 已提交
1083
                        } else {
1084 1085 1086 1087
                            self.end = self.end.offset(-1);

                            Some(transmute(self.end))
                        }
B
Brian Anderson 已提交
1088 1089 1090 1091 1092 1093 1094 1095
                    }
                }
            }
        }
    }
}

/// Immutable slice iterator
1096
#[experimental = "needs review"]
1097
pub struct Items<'a, T: 'a> {
B
Brian Anderson 已提交
1098 1099 1100 1101 1102 1103 1104
    ptr: *const T,
    end: *const T,
    marker: marker::ContravariantLifetime<'a>
}

iterator!{struct Items -> *const T, &'a T}

1105
#[experimental = "needs review"]
B
Brian Anderson 已提交
1106 1107
impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}

1108
#[experimental = "needs review"]
B
Brian Anderson 已提交
1109 1110 1111 1112
impl<'a, T> Clone for Items<'a, T> {
    fn clone(&self) -> Items<'a, T> { *self }
}

1113
#[experimental = "needs review"]
B
Brian Anderson 已提交
1114
impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
1115
    #[inline]
B
Brian Anderson 已提交
1116 1117 1118 1119
    fn indexable(&self) -> uint {
        let (exact, _) = self.size_hint();
        exact
    }
1120

B
Brian Anderson 已提交
1121 1122
    #[inline]
    fn idx(&mut self, index: uint) -> Option<&'a T> {
1123
        unsafe {
B
Brian Anderson 已提交
1124
            if index < self.indexable() {
1125 1126 1127 1128 1129 1130
                if mem::size_of::<T>() == 0 {
                    // Use a non-null pointer value
                    Some(transmute(1u))
                } else {
                    Some(transmute(self.ptr.offset(index as int)))
                }
B
Brian Anderson 已提交
1131 1132 1133 1134 1135 1136 1137
            } else {
                None
            }
        }
    }
}

A
Aaron Turon 已提交
1138
/// Mutable slice iterator.
1139
#[experimental = "needs review"]
1140
pub struct MutItems<'a, T: 'a> {
B
Brian Anderson 已提交
1141 1142 1143 1144 1145 1146 1147 1148
    ptr: *mut T,
    end: *mut T,
    marker: marker::ContravariantLifetime<'a>,
    marker2: marker::NoCopy
}

iterator!{struct MutItems -> *mut T, &'a mut T}

1149
#[experimental = "needs review"]
B
Brian Anderson 已提交
1150 1151
impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}

A
Aaron Turon 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
/// An abstraction over the splitting iterators, so that splitn, splitn_mut etc
/// can be implemented once.
trait SplitsIter<E>: DoubleEndedIterator<E> {
    /// Mark the underlying iterator as complete, extracting the remaining
    /// portion of the slice.
    fn finish(&mut self) -> Option<E>;
}

/// An iterator over subslices separated by elements that match a predicate
/// function.
1162
#[experimental = "needs review"]
1163 1164 1165 1166 1167 1168
pub struct Splits<'a, T:'a> {
    v: &'a [T],
    pred: |t: &T|: 'a -> bool,
    finished: bool
}

1169
#[experimental = "needs review"]
B
Brian Anderson 已提交
1170 1171 1172 1173 1174 1175
impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a [T]> {
        if self.finished { return None; }

        match self.v.iter().position(|x| (self.pred)(x)) {
A
Aaron Turon 已提交
1176
            None => self.finish(),
B
Brian Anderson 已提交
1177
            Some(idx) => {
1178 1179
                let ret = Some(self.v[..idx]);
                self.v = self.v[idx + 1..];
B
Brian Anderson 已提交
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
                ret
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        if self.finished {
            (0, Some(0))
        } else {
            (1, Some(self.v.len() + 1))
        }
    }
}

1195
#[experimental = "needs review"]
B
Brian Anderson 已提交
1196 1197 1198 1199 1200 1201
impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a [T]> {
        if self.finished { return None; }

        match self.v.iter().rposition(|x| (self.pred)(x)) {
A
Aaron Turon 已提交
1202
            None => self.finish(),
B
Brian Anderson 已提交
1203
            Some(idx) => {
1204 1205
                let ret = Some(self.v[idx + 1..]);
                self.v = self.v[..idx];
B
Brian Anderson 已提交
1206 1207 1208 1209 1210 1211
                ret
            }
        }
    }
}

A
Aaron Turon 已提交
1212 1213 1214 1215 1216 1217 1218
impl<'a, T> SplitsIter<&'a [T]> for Splits<'a, T> {
    #[inline]
    fn finish(&mut self) -> Option<&'a [T]> {
        if self.finished { None } else { self.finished = true; Some(self.v) }
    }
}

B
Brian Anderson 已提交
1219 1220
/// An iterator over the subslices of the vector which are separated
/// by elements that match `pred`.
1221
#[experimental = "needs review"]
1222 1223 1224 1225 1226 1227
pub struct MutSplits<'a, T:'a> {
    v: &'a mut [T],
    pred: |t: &T|: 'a -> bool,
    finished: bool
}

A
Aaron Turon 已提交
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239
impl<'a, T> SplitsIter<&'a mut [T]> for MutSplits<'a, T> {
    #[inline]
    fn finish(&mut self) -> Option<&'a mut [T]> {
        if self.finished {
            None
        } else {
            self.finished = true;
            Some(mem::replace(&mut self.v, &mut []))
        }
    }
}

1240
#[experimental = "needs review"]
B
Brian Anderson 已提交
1241 1242 1243 1244 1245
impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a mut [T]> {
        if self.finished { return None; }

A
Aaron Turon 已提交
1246 1247 1248 1249 1250 1251
        let idx_opt = { // work around borrowck limitations
            let pred = &mut self.pred;
            self.v.iter().position(|x| (*pred)(x))
        };
        match idx_opt {
            None => self.finish(),
B
Brian Anderson 已提交
1252 1253
            Some(idx) => {
                let tmp = mem::replace(&mut self.v, &mut []);
A
Aaron Turon 已提交
1254
                let (head, tail) = tmp.split_at_mut(idx);
1255
                self.v = tail[mut 1..];
B
Brian Anderson 已提交
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272
                Some(head)
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        if self.finished {
            (0, Some(0))
        } else {
            // if the predicate doesn't match anything, we yield one slice
            // if it matches every element, we yield len+1 empty slices.
            (1, Some(self.v.len() + 1))
        }
    }
}

1273
#[experimental = "needs review"]
B
Brian Anderson 已提交
1274 1275 1276 1277 1278
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
    #[inline]
    fn next_back(&mut self) -> Option<&'a mut [T]> {
        if self.finished { return None; }

A
Aaron Turon 已提交
1279 1280 1281 1282 1283 1284
        let idx_opt = { // work around borrowck limitations
            let pred = &mut self.pred;
            self.v.iter().rposition(|x| (*pred)(x))
        };
        match idx_opt {
            None => self.finish(),
B
Brian Anderson 已提交
1285 1286
            Some(idx) => {
                let tmp = mem::replace(&mut self.v, &mut []);
A
Aaron Turon 已提交
1287
                let (head, tail) = tmp.split_at_mut(idx);
B
Brian Anderson 已提交
1288
                self.v = head;
1289
                Some(tail[mut 1..])
B
Brian Anderson 已提交
1290 1291 1292 1293 1294
            }
        }
    }
}

A
Aaron Turon 已提交
1295 1296
/// An iterator over subslices separated by elements that match a predicate
/// function, splitting at most a fixed number of times.
1297
#[experimental = "needs review"]
A
Aaron Turon 已提交
1298 1299
pub struct SplitsN<I> {
    iter: I,
1300 1301 1302 1303
    count: uint,
    invert: bool
}

1304
#[experimental = "needs review"]
A
Aaron Turon 已提交
1305
impl<E, I: SplitsIter<E>> Iterator<E> for SplitsN<I> {
B
Brian Anderson 已提交
1306
    #[inline]
A
Aaron Turon 已提交
1307
    fn next(&mut self) -> Option<E> {
B
Brian Anderson 已提交
1308
        if self.count == 0 {
A
Aaron Turon 已提交
1309
            self.iter.finish()
B
Brian Anderson 已提交
1310 1311 1312
        } else {
            self.count -= 1;
            if self.invert { self.iter.next_back() } else { self.iter.next() }
1313 1314 1315 1316
        }
    }

    #[inline]
B
Brian Anderson 已提交
1317
    fn size_hint(&self) -> (uint, Option<uint>) {
A
Aaron Turon 已提交
1318 1319
        let (lower, upper_opt) = self.iter.size_hint();
        (lower, upper_opt.map(|upper| cmp::min(self.count + 1, upper)))
1320
    }
B
Brian Anderson 已提交
1321 1322
}

A
Aaron Turon 已提交
1323
/// An iterator over overlapping subslices of length `size`.
1324
#[deriving(Clone)]
1325
#[experimental = "needs review"]
1326 1327 1328 1329 1330
pub struct Windows<'a, T:'a> {
    v: &'a [T],
    size: uint
}

B
Brian Anderson 已提交
1331
impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
1332
    #[inline]
B
Brian Anderson 已提交
1333 1334 1335 1336
    fn next(&mut self) -> Option<&'a [T]> {
        if self.size > self.v.len() {
            None
        } else {
1337 1338
            let ret = Some(self.v[..self.size]);
            self.v = self.v[1..];
B
Brian Anderson 已提交
1339 1340
            ret
        }
1341 1342 1343
    }

    #[inline]
B
Brian Anderson 已提交
1344 1345 1346 1347 1348
    fn size_hint(&self) -> (uint, Option<uint>) {
        if self.size > self.v.len() {
            (0, Some(0))
        } else {
            let x = self.v.len() - self.size;
1349
            (x.saturating_add(1), x.checked_add(1u))
1350 1351
        }
    }
B
Brian Anderson 已提交
1352 1353
}

A
Aaron Turon 已提交
1354 1355
/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a
/// time).
B
Brian Anderson 已提交
1356
///
A
Aaron Turon 已提交
1357 1358
/// When the slice len is not evenly divided by the chunk size, the last slice
/// of the iteration will be the remainder.
B
Brian Anderson 已提交
1359
#[deriving(Clone)]
1360
#[experimental = "needs review"]
1361 1362 1363 1364 1365
pub struct Chunks<'a, T:'a> {
    v: &'a [T],
    size: uint
}

1366
#[experimental = "needs review"]
B
Brian Anderson 已提交
1367
impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
1368
    #[inline]
B
Brian Anderson 已提交
1369 1370 1371 1372 1373
    fn next(&mut self) -> Option<&'a [T]> {
        if self.v.len() == 0 {
            None
        } else {
            let chunksz = cmp::min(self.v.len(), self.size);
1374
            let (fst, snd) = self.v.split_at(chunksz);
B
Brian Anderson 已提交
1375 1376
            self.v = snd;
            Some(fst)
1377 1378 1379 1380
        }
    }

    #[inline]
B
Brian Anderson 已提交
1381 1382 1383 1384 1385 1386 1387 1388
    fn size_hint(&self) -> (uint, Option<uint>) {
        if self.v.len() == 0 {
            (0, Some(0))
        } else {
            let (n, rem) = div_rem(self.v.len(), self.size);
            let n = if rem > 0 { n+1 } else { n };
            (n, Some(n))
        }
1389
    }
B
Brian Anderson 已提交
1390
}
1391

1392
#[experimental = "needs review"]
B
Brian Anderson 已提交
1393
impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
1394
    #[inline]
B
Brian Anderson 已提交
1395 1396 1397 1398 1399 1400
    fn next_back(&mut self) -> Option<&'a [T]> {
        if self.v.len() == 0 {
            None
        } else {
            let remainder = self.v.len() % self.size;
            let chunksz = if remainder != 0 { remainder } else { self.size };
1401
            let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
B
Brian Anderson 已提交
1402 1403 1404
            self.v = fst;
            Some(snd)
        }
1405
    }
B
Brian Anderson 已提交
1406
}
1407

1408
#[experimental = "needs review"]
B
Brian Anderson 已提交
1409
impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
1410
    #[inline]
B
Brian Anderson 已提交
1411 1412
    fn indexable(&self) -> uint {
        self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
1413 1414
    }

B
Brian Anderson 已提交
1415 1416 1417 1418 1419 1420
    #[inline]
    fn idx(&mut self, index: uint) -> Option<&'a [T]> {
        if index < self.indexable() {
            let lo = index * self.size;
            let mut hi = lo + self.size;
            if hi < lo || hi > self.v.len() { hi = self.v.len(); }
1421

1422
            Some(self.v[lo..hi])
B
Brian Anderson 已提交
1423 1424
        } else {
            None
1425 1426
        }
    }
B
Brian Anderson 已提交
1427
}
1428

A
Aaron Turon 已提交
1429 1430 1431
/// An iterator over a slice in (non-overlapping) mutable chunks (`size`
/// elements at a time). When the slice len is not evenly divided by the chunk
/// size, the last slice of the iteration will be the remainder.
1432
#[experimental = "needs review"]
1433 1434 1435 1436 1437
pub struct MutChunks<'a, T:'a> {
    v: &'a mut [T],
    chunk_size: uint
}

1438
#[experimental = "needs review"]
B
Brian Anderson 已提交
1439 1440 1441 1442 1443 1444 1445 1446
impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a mut [T]> {
        if self.v.len() == 0 {
            None
        } else {
            let sz = cmp::min(self.v.len(), self.chunk_size);
            let tmp = mem::replace(&mut self.v, &mut []);
A
Aaron Turon 已提交
1447
            let (head, tail) = tmp.split_at_mut(sz);
B
Brian Anderson 已提交
1448 1449
            self.v = tail;
            Some(head)
1450 1451 1452 1453
        }
    }

    #[inline]
B
Brian Anderson 已提交
1454 1455 1456 1457 1458 1459 1460 1461
    fn size_hint(&self) -> (uint, Option<uint>) {
        if self.v.len() == 0 {
            (0, Some(0))
        } else {
            let (n, rem) = div_rem(self.v.len(), self.chunk_size);
            let n = if rem > 0 { n + 1 } else { n };
            (n, Some(n))
        }
1462
    }
B
Brian Anderson 已提交
1463
}
1464

1465
#[experimental = "needs review"]
B
Brian Anderson 已提交
1466
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
1467
    #[inline]
B
Brian Anderson 已提交
1468 1469 1470 1471 1472 1473 1474 1475
    fn next_back(&mut self) -> Option<&'a mut [T]> {
        if self.v.len() == 0 {
            None
        } else {
            let remainder = self.v.len() % self.chunk_size;
            let sz = if remainder != 0 { remainder } else { self.chunk_size };
            let tmp = mem::replace(&mut self.v, &mut []);
            let tmp_len = tmp.len();
A
Aaron Turon 已提交
1476
            let (head, tail) = tmp.split_at_mut(tmp_len - sz);
B
Brian Anderson 已提交
1477 1478 1479
            self.v = head;
            Some(tail)
        }
1480
    }
B
Brian Anderson 已提交
1481
}
1482 1483 1484



1485 1486 1487 1488 1489 1490 1491
/// The result of calling `binary_search`.
///
/// `Found` means the search succeeded, and the contained value is the
/// index of the matching element. `NotFound` means the search
/// succeeded, and the contained value is an index where a matching
/// value could be inserted while maintaining sort order.
#[deriving(PartialEq, Show)]
1492
#[experimental = "needs review"]
1493 1494 1495 1496 1497 1498 1499
pub enum BinarySearchResult {
    /// The index of the found value.
    Found(uint),
    /// The index where the value should have been found.
    NotFound(uint)
}

1500
#[experimental = "needs review"]
1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
impl BinarySearchResult {
    /// Converts a `Found` to `Some`, `NotFound` to `None`.
    /// Similar to `Result::ok`.
    pub fn found(&self) -> Option<uint> {
        match *self {
            Found(i) => Some(i),
            NotFound(_) => None
        }
    }

    /// Convert a `Found` to `None`, `NotFound` to `Some`.
    /// Similar to `Result::err`.
    pub fn not_found(&self) -> Option<uint> {
        match *self {
            Found(_) => None,
            NotFound(i) => Some(i)
        }
    }
}


1522

B
Brian Anderson 已提交
1523 1524 1525
//
// Free functions
//
1526

B
Brian Anderson 已提交
1527 1528 1529
/**
 * Converts a pointer to A into a slice of length 1 (without copying).
 */
1530
#[unstable = "waiting for DST"]
B
Brian Anderson 已提交
1531 1532
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
    unsafe {
1533
        transmute(RawSlice { data: s, len: 1 })
B
Brian Anderson 已提交
1534 1535 1536 1537 1538 1539
    }
}

/**
 * Converts a pointer to A into a slice of length 1 (without copying).
 */
1540
#[unstable = "waiting for DST"]
B
Brian Anderson 已提交
1541 1542 1543
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
    unsafe {
        let ptr: *const A = transmute(s);
1544
        transmute(RawSlice { data: ptr, len: 1 })
1545 1546 1547
    }
}

B
Brian Anderson 已提交
1548 1549 1550 1551 1552 1553 1554



//
// Submodules
//

1555
/// Unsafe operations
1556
#[experimental = "needs review"]
1557
pub mod raw {
A
Alex Crichton 已提交
1558
    use mem::transmute;
1559 1560
    use ptr::RawPtr;
    use raw::Slice;
1561
    use option::{None, Option, Some};
1562 1563 1564 1565 1566 1567

    /**
     * Form a slice from a pointer and length (as a number of units,
     * not bytes).
     */
    #[inline]
1568
    pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
                               -> U {
        f(transmute(Slice {
            data: p,
            len: len
        }))
    }

    /**
     * Form a slice from a pointer and length (as a number of units,
     * not bytes).
     */
    #[inline]
    pub unsafe fn mut_buf_as_slice<T,
                                   U>(
                                   p: *mut T,
                                   len: uint,
                                   f: |v: &mut [T]| -> U)
                                   -> U {
        f(transmute(Slice {
1588
            data: p as *const T,
1589 1590 1591 1592 1593 1594
            len: len
        }))
    }

    /**
     * Returns a pointer to first element in slice and adjusts
1595 1596
     * slice so it no longer contains that element. Returns None
     * if the slice is empty. O(1).
1597
     */
1598
     #[inline]
1599
    pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
1600
        if slice.len == 0 { return None; }
1601
        let head: *const T = slice.data;
1602 1603
        slice.data = slice.data.offset(1);
        slice.len -= 1;
1604
        Some(head)
1605 1606 1607 1608
    }

    /**
     * Returns a pointer to last element in slice and adjusts
1609 1610
     * slice so it no longer contains that element. Returns None
     * if the slice is empty. O(1).
1611
     */
1612
     #[inline]
1613
    pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
1614
        if slice.len == 0 { return None; }
1615
        let tail: *const T = slice.data.offset((slice.len - 1) as int);
1616
        slice.len -= 1;
1617
        Some(tail)
1618 1619 1620 1621
    }
}

/// Operations on `[u8]`.
1622
#[experimental = "needs review"]
1623
pub mod bytes {
J
Jorge Aparicio 已提交
1624
    use kinds::Sized;
1625
    use ptr;
1626
    use slice::SlicePrelude;
1627 1628

    /// A trait for operations on mutable `[u8]`s.
J
Jorge Aparicio 已提交
1629
    pub trait MutableByteVector for Sized? {
1630
        /// Sets all bytes of the receiver to the given value.
J
Jorge Aparicio 已提交
1631
        fn set_memory(&mut self, value: u8);
1632 1633
    }

J
Jorge Aparicio 已提交
1634
    impl MutableByteVector for [u8] {
1635
        #[inline]
1636
        #[allow(experimental)]
J
Jorge Aparicio 已提交
1637
        fn set_memory(&mut self, value: u8) {
1638 1639 1640 1641 1642 1643
            unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
        }
    }

    /// Copies data from `src` to `dst`
    ///
1644
    /// `src` and `dst` must not overlap. Panics if the length of `dst`
1645 1646 1647
    /// is less than the length of `src`.
    #[inline]
    pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
1648 1649 1650 1651 1652 1653 1654
        let len_src = src.len();
        assert!(dst.len() >= len_src);
        unsafe {
            ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
                                            src.as_ptr(),
                                            len_src);
        }
1655 1656 1657 1658 1659
    }
}



B
Brian Anderson 已提交
1660 1661 1662
//
// Boilerplate traits
//
1663

1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
#[unstable = "waiting for DST"]
impl<T: PartialEq> PartialEq for [T] {
    fn eq(&self, other: &[T]) -> bool {
        self.len() == other.len() &&
            order::eq(self.iter(), other.iter())
    }
    fn ne(&self, other: &[T]) -> bool {
        self.len() != other.len() ||
            order::ne(self.iter(), other.iter())
    }
}

#[unstable = "waiting for DST"]
impl<T: Eq> Eq for [T] {}

1679
#[unstable = "waiting for DST"]
J
Jorge Aparicio 已提交
1680
impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for [T] {
1681 1682 1683
    #[inline]
    fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
1684

N
Nick Cameron 已提交
1685
#[unstable = "waiting for DST"]
N
Nick Cameron 已提交
1686
impl<'a,T:PartialEq, V: AsSlice<T>> Equiv<V> for &'a mut [T] {
N
Nick Cameron 已提交
1687 1688 1689 1690
    #[inline]
    fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}

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
#[unstable = "waiting for DST"]
impl<T: Ord> Ord for [T] {
    fn cmp(&self, other: &[T]) -> Ordering {
        order::cmp(self.iter(), other.iter())
    }
}

#[unstable = "waiting for DST"]
impl<T: PartialOrd> PartialOrd for [T] {
    #[inline]
    fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
        order::partial_cmp(self.iter(), other.iter())
    }
    #[inline]
    fn lt(&self, other: &[T]) -> bool {
        order::lt(self.iter(), other.iter())
    }
    #[inline]
    fn le(&self, other: &[T]) -> bool {
        order::le(self.iter(), other.iter())
    }
    #[inline]
    fn ge(&self, other: &[T]) -> bool {
        order::ge(self.iter(), other.iter())
    }
    #[inline]
    fn gt(&self, other: &[T]) -> bool {
        order::gt(self.iter(), other.iter())
    }
}

J
Julian Orth 已提交
1722 1723
/// Extension methods for immutable slices containing integers.
#[experimental]
J
Jorge Aparicio 已提交
1724
pub trait ImmutableIntSlice<U, S> for Sized? {
J
Julian Orth 已提交
1725
    /// Converts the slice to an immutable slice of unsigned integers with the same width.
J
Jorge Aparicio 已提交
1726
    fn as_unsigned<'a>(&'a self) -> &'a [U];
J
Julian Orth 已提交
1727
    /// Converts the slice to an immutable slice of signed integers with the same width.
J
Jorge Aparicio 已提交
1728
    fn as_signed<'a>(&'a self) -> &'a [S];
J
Julian Orth 已提交
1729 1730 1731 1732
}

/// Extension methods for mutable slices containing integers.
#[experimental]
J
Jorge Aparicio 已提交
1733
pub trait MutableIntSlice<U, S> for Sized?: ImmutableIntSlice<U, S> {
J
Julian Orth 已提交
1734
    /// Converts the slice to a mutable slice of unsigned integers with the same width.
J
Jorge Aparicio 已提交
1735
    fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U];
J
Julian Orth 已提交
1736
    /// Converts the slice to a mutable slice of signed integers with the same width.
J
Jorge Aparicio 已提交
1737
    fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S];
J
Julian Orth 已提交
1738 1739 1740 1741 1742
}

macro_rules! impl_immut_int_slice {
    ($u:ty, $s:ty, $t:ty) => {
        #[experimental]
J
Jorge Aparicio 已提交
1743
        impl ImmutableIntSlice<$u, $s> for [$t] {
J
Julian Orth 已提交
1744
            #[inline]
J
Jorge Aparicio 已提交
1745
            fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
J
Julian Orth 已提交
1746
            #[inline]
J
Jorge Aparicio 已提交
1747
            fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
J
Julian Orth 已提交
1748 1749 1750 1751 1752 1753
        }
    }
}
macro_rules! impl_mut_int_slice {
    ($u:ty, $s:ty, $t:ty) => {
        #[experimental]
J
Jorge Aparicio 已提交
1754
        impl MutableIntSlice<$u, $s> for [$t] {
J
Julian Orth 已提交
1755
            #[inline]
J
Jorge Aparicio 已提交
1756
            fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } }
J
Julian Orth 已提交
1757
            #[inline]
J
Jorge Aparicio 已提交
1758
            fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute(self) } }
J
Julian Orth 已提交
1759 1760 1761 1762 1763 1764
        }
    }
}

macro_rules! impl_int_slice {
    ($u:ty, $s:ty) => {
J
Jorge Aparicio 已提交
1765 1766 1767 1768
        impl_immut_int_slice!($u, $s, $u)
        impl_immut_int_slice!($u, $s, $s)
        impl_mut_int_slice!($u, $s, $u)
        impl_mut_int_slice!($u, $s, $s)
J
Julian Orth 已提交
1769 1770 1771 1772 1773 1774 1775 1776
    }
}

impl_int_slice!(u8,   i8)
impl_int_slice!(u16,  i16)
impl_int_slice!(u32,  i32)
impl_int_slice!(u64,  i64)
impl_int_slice!(uint, int)