Skip to content

Commit

Permalink
Prelude: rename and consolidate extension traits
Browse files Browse the repository at this point in the history
This commit renames a number of extension traits for slices and string
slices, now that they have been refactored for DST. In many cases,
multiple extension traits could now be consolidated. Further
consolidation will be possible with generalized where clauses.

The renamings are consistent with the [new `-Prelude`
suffix](rust-lang/rfcs#344). There are probably
a few more candidates for being renamed this way, but that is left for
API stabilization of the relevant modules.

Because this renames traits, it is a:

[breaking-change]

However, I do not expect any code that currently uses the standard
library to actually break.

Closes rust-lang#17917
  • Loading branch information
aturon committed Nov 6, 2014
1 parent e84e7a0 commit cfafc1b
Show file tree
Hide file tree
Showing 45 changed files with 483 additions and 487 deletions.
10 changes: 5 additions & 5 deletions src/etc/unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def emit_bsearch_range_table(f):
f.write("""
fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
use core::cmp::{Equal, Less, Greater};
use core::slice::ImmutableSlice;
use core::slice::SlicePrelude;
r.binary_search(|&(lo,hi)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
Expand Down Expand Up @@ -351,7 +351,7 @@ def emit_conversions_module(f, lowerupper, upperlower):
f.write("pub mod conversions {")
f.write("""
use core::cmp::{Equal, Less, Greater};
use core::slice::ImmutableSlice;
use core::slice::SlicePrelude;
use core::tuple::Tuple2;
use core::option::{Option, Some, None};
use core::slice;
Expand Down Expand Up @@ -390,7 +390,7 @@ def emit_conversions_module(f, lowerupper, upperlower):

def emit_grapheme_module(f, grapheme_table, grapheme_cats):
f.write("""pub mod grapheme {
use core::slice::ImmutableSlice;
use core::slice::SlicePrelude;
use core::slice;
#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -430,7 +430,7 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
def emit_charwidth_module(f, width_table):
f.write("pub mod charwidth {\n")
f.write(" use core::option::{Option, Some, None};\n")
f.write(" use core::slice::ImmutableSlice;\n")
f.write(" use core::slice::SlicePrelude;\n")
f.write(" use core::slice;\n")
f.write("""
fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
Expand Down Expand Up @@ -530,7 +530,7 @@ def comp_pfun(char):
f.write("""
fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
use core::cmp::{Equal, Less, Greater};
use core::slice::ImmutableSlice;
use core::slice::SlicePrelude;
use core::slice;
match r.binary_search(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ mod tests {
use core::kinds::Sized;
use std::mem;

use slice::ImmutableSlice;
use slice::SlicePrelude;
use super::{Hash, Hasher, Writer};

struct MyWriterHasher;
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/hash/sip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ mod tests {

use str::Str;
use string::String;
use slice::{AsSlice, ImmutableSlice};
use slice::{AsSlice, SlicePrelude};
use vec::Vec;

use super::super::{Hash, Writer};
Expand Down
210 changes: 56 additions & 154 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
//!
//! ## Traits
//!
//! A number of traits add methods that allow you to accomplish tasks with slices.
//! These traits include `ImmutableSlice`, which is defined for `&[T]` types,
//! `MutableSlice`, defined for `&mut [T]` types, and `Slice` and `SliceMut`
//! which are defined for `[T]`.
//! A number of traits add methods that allow you to accomplish tasks
//! with slices, the most important being `SlicePrelude`. Other traits
//! apply only to slices of elements satisfying certain bounds (like
//! `Ord`).
//!
//! An example is the `slice` method which enables slicing syntax `[a..b]` that
//! returns an immutable "view" into a `Vec` or another slice from the index
Expand Down Expand Up @@ -99,11 +99,11 @@ use core::iter::{range_step, MultiplicativeIterator};

use vec::Vec;

pub use core::slice::{Chunks, AsSlice, ImmutableSlice, ImmutablePartialEqSlice};
pub use core::slice::{ImmutableOrdSlice, MutableSlice, Items, MutItems};
pub use core::slice::{Chunks, AsSlice, SlicePrelude, PartialEqSlicePrelude};
pub use core::slice::{OrdSlicePrelude, SlicePrelude, Items, MutItems};
pub use core::slice::{ImmutableIntSlice, MutableIntSlice};
pub use core::slice::{MutSplits, MutChunks, Splits};
pub use core::slice::{bytes, mut_ref_slice, ref_slice, MutableCloneableSlice};
pub use core::slice::{bytes, mut_ref_slice, ref_slice, CloneSlicePrelude};
pub use core::slice::{Found, NotFound};

// Functional utilities
Expand Down Expand Up @@ -266,29 +266,13 @@ impl<T: Clone> Iterator<Vec<T>> for Permutations<T> {
}
}

/// Extension methods for vector slices with cloneable elements
pub trait CloneableVector<T> for Sized? {
/// Copies `self` into a new `Vec`.
fn to_vec(&self) -> Vec<T>;
}

impl<T: Clone> CloneableVector<T> for [T] {
/// Returns a copy of `v`.
#[inline]
fn to_vec(&self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}
}

#[experimental]
pub trait BoxedSlice<T> {
/// Extension methods for boxed slices.
pub trait BoxedSlicePrelude<T> {
/// Convert `self` into a vector without clones or allocation.
fn into_vec(self) -> Vec<T>;
}

impl<T> BoxedSlice<T> for Box<[T]> {
impl<T> BoxedSlicePrelude<T> for Box<[T]> {
#[experimental]
fn into_vec(mut self) -> Vec<T> {
unsafe {
Expand All @@ -299,8 +283,11 @@ impl<T> BoxedSlice<T> for Box<[T]> {
}
}

/// Extension methods for vectors containing `Clone` elements.
pub trait ImmutableCloneableVector<T> for Sized? {
/// Allocating extension methods for slices containing `Clone` elements.
pub trait CloneSliceAllocPrelude<T> for Sized? {
/// Copies `self` into a new `Vec`.
fn to_vec(&self) -> Vec<T>;

/// Partitions the vector into two vectors `(a, b)`, where all
/// elements of `a` satisfy `f` and all elements of `b` do not.
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
Expand Down Expand Up @@ -332,7 +319,16 @@ pub trait ImmutableCloneableVector<T> for Sized? {
fn permutations(&self) -> Permutations<T>;
}

impl<T: Clone> ImmutableCloneableVector<T> for [T] {
impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
/// Returns a copy of `v`.
#[inline]
fn to_vec(&self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}


#[inline]
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
let mut lefts = Vec::new();
Expand Down Expand Up @@ -562,9 +558,36 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
}
}

/// Extension methods for vectors such that their elements are
/// mutable.
pub trait MutableSliceAllocating<T> for Sized? {
/// Allocating extension methods for slices on Ord values.
#[experimental = "likely to merge with other traits"]
pub trait OrdSliceAllocPrelude<T> for Sized? {
/// Sorts the slice, in place.
///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
///
/// # Example
///
/// ```rust
/// let mut v = [-5i, 4, 1, -3, 2];
///
/// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]);
/// ```
#[experimental]
fn sort(&mut self);
}

impl<T: Ord> OrdSliceAllocPrelude<T> for [T] {
#[experimental]
#[inline]
fn sort(&mut self) {
self.sort_by(|a, b| a.cmp(b))
}
}

/// Allocating extension methods for slices.
#[experimental = "likely to merge with other traits"]
pub trait SliceAllocPrelude<T> for Sized? {
/// Sorts the slice, in place, using `compare` to compare
/// elements.
///
Expand Down Expand Up @@ -608,7 +631,7 @@ pub trait MutableSliceAllocating<T> for Sized? {
fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
}

impl<T> MutableSliceAllocating<T> for [T] {
impl<T> SliceAllocPrelude<T> for [T] {
#[inline]
fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
merge_sort(self, compare)
Expand All @@ -623,127 +646,6 @@ impl<T> MutableSliceAllocating<T> for [T] {
}
}

/// Methods for mutable vectors with orderable elements, such as
/// in-place sorting.
pub trait MutableOrdSlice<T> for Sized? {
/// Sorts the slice, in place.
///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
///
/// # Example
///
/// ```rust
/// let mut v = [-5i, 4, 1, -3, 2];
///
/// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]);
/// ```
fn sort(&mut self);

/// 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);
/// ```
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);
/// ```
fn prev_permutation(&mut self) -> bool;
}

impl<T: Ord> MutableOrdSlice<T> for [T] {
#[inline]
fn sort(&mut self) {
self.sort_by(|a, b| a.cmp(b))
}

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
}

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

/// Unsafe operations
pub mod raw {
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
Expand Down
16 changes: 8 additions & 8 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ use core::fmt;
use core::cmp;
use core::iter::AdditiveIterator;
use core::kinds::Sized;
use core::prelude::{Char, Clone, Eq, Equiv, ImmutableSlice};
use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering};
use core::prelude::{Char, Clone, Eq, Equiv};
use core::prelude::{Iterator, SlicePrelude, None, Option, Ord, Ordering};
use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2};
use core::prelude::{range};

Expand All @@ -73,8 +73,8 @@ pub use core::str::{CharSplitsN, AnyLines, MatchIndices, StrSplits};
pub use core::str::{Utf16CodeUnits, eq_slice, is_utf8, is_utf16, Utf16Items};
pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
pub use core::str::{Str, StrSlice};
pub use unicode::str::{UnicodeStrSlice, Words, Graphemes, GraphemeIndices};
pub use core::str::{Str, StrPrelude};
pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices};

/*
Section: Creating a string
Expand Down Expand Up @@ -790,10 +790,10 @@ mod tests {
use std::iter::{Iterator, DoubleEndedIterator};

use super::*;
use std::slice::{AsSlice, ImmutableSlice};
use std::slice::{AsSlice, SlicePrelude};
use string::String;
use vec::Vec;
use slice::CloneableVector;
use slice::CloneSliceAllocPrelude;

use unicode::char::UnicodeChar;

Expand Down Expand Up @@ -2240,8 +2240,8 @@ mod bench {
use test::black_box;
use super::*;
use std::iter::{Iterator, DoubleEndedIterator};
use std::str::StrSlice;
use std::slice::ImmutableSlice;
use std::str::StrPrelude;
use std::slice::SlicePrelude;

#[bench]
fn char_iterator(b: &mut Bencher) {
Expand Down
Loading

1 comment on commit cfafc1b

@aturon
Copy link
Owner Author

@aturon aturon commented on cfafc1b Nov 6, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=alexcrichton

Please sign in to comment.