Skip to content

Prelude: rename and consolidate extension traits #18559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 6, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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? {
Copy link
Member

Choose a reason for hiding this comment

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

I wonder, could this be called OrdSlicePrelude, and then we could use modules/renaming to import both this and the libcore version into the prelude?

Copy link
Member

Choose a reason for hiding this comment

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

That may not help the docs, however.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, so this is why I was thinking it might be nice for std to just define its own set of extension traits that hook into the underlying traits from core etc. I can't see a way to do that without duplicating the docs, though :-/

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