mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
auto merge of #17447 : thestinger/rust/silly_string, r=aturon
This provides a way to pass `&[T]` to functions taking `&U` where `U` is a `Vec<T>`. This is useful in many cases not covered by the Equiv trait or methods like `find_with` on TreeMap.
This commit is contained in:
commit
bc649ba8f8
@ -28,7 +28,7 @@ use slice::CloneableVector;
|
|||||||
use str;
|
use str;
|
||||||
use str::{CharRange, StrAllocating, MaybeOwned, Owned};
|
use str::{CharRange, StrAllocating, MaybeOwned, Owned};
|
||||||
use str::Slice as MaybeOwnedSlice; // So many `Slice`s...
|
use str::Slice as MaybeOwnedSlice; // So many `Slice`s...
|
||||||
use vec::Vec;
|
use vec::{DerefVec, Vec, as_vec};
|
||||||
|
|
||||||
/// A growable string stored as a UTF-8 encoded buffer.
|
/// A growable string stored as a UTF-8 encoded buffer.
|
||||||
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
|
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
@ -973,6 +973,24 @@ impl ops::Slice<uint, str> for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper type providing a `&String` reference via `Deref`.
|
||||||
|
#[experimental]
|
||||||
|
pub struct DerefString<'a> {
|
||||||
|
x: DerefVec<'a, u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref<String> for DerefString<'a> {
|
||||||
|
fn deref<'b>(&'b self) -> &'b String {
|
||||||
|
unsafe { mem::transmute(&*self.x) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a string slice to a wrapper type providing a `&String` reference.
|
||||||
|
#[experimental]
|
||||||
|
pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
|
||||||
|
DerefString { x: as_vec(x.as_bytes()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Unsafe operations
|
/// Unsafe operations
|
||||||
#[unstable = "waiting on raw module conventions"]
|
#[unstable = "waiting on raw module conventions"]
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
@ -1039,9 +1057,15 @@ mod tests {
|
|||||||
use {Mutable, MutableSeq};
|
use {Mutable, MutableSeq};
|
||||||
use str;
|
use str;
|
||||||
use str::{Str, StrSlice, Owned};
|
use str::{Str, StrSlice, Owned};
|
||||||
use super::String;
|
use super::{as_string, String};
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_as_string() {
|
||||||
|
let x = "foo";
|
||||||
|
assert_eq!(x, as_string(x).as_slice());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str() {
|
fn test_from_str() {
|
||||||
let owned: Option<::std::string::String> = from_str("string");
|
let owned: Option<::std::string::String> = from_str("string");
|
||||||
|
@ -18,7 +18,7 @@ use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
|
|||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::kinds::marker::InvariantType;
|
use core::kinds::marker::{ContravariantLifetime, InvariantType};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::num;
|
use core::num;
|
||||||
use core::ops;
|
use core::ops;
|
||||||
@ -1875,6 +1875,39 @@ pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
|
|||||||
(ts, us)
|
(ts, us)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper type providing a `&Vec<T>` reference via `Deref`.
|
||||||
|
#[experimental]
|
||||||
|
pub struct DerefVec<'a, T> {
|
||||||
|
x: Vec<T>,
|
||||||
|
l: ContravariantLifetime<'a>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Deref<Vec<T>> for DerefVec<'a, T> {
|
||||||
|
fn deref<'b>(&'b self) -> &'b Vec<T> {
|
||||||
|
&self.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent the inner `Vec<T>` from attempting to deallocate memory.
|
||||||
|
#[unsafe_destructor]
|
||||||
|
impl<'a, T> Drop for DerefVec<'a, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.x.len = 0;
|
||||||
|
self.x.cap = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a slice to a wrapper type providing a `&Vec<T>` reference.
|
||||||
|
#[experimental]
|
||||||
|
pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
|
||||||
|
unsafe {
|
||||||
|
DerefVec {
|
||||||
|
x: Vec::from_raw_parts(x.len(), x.len(), x.as_ptr() as *mut T),
|
||||||
|
l: ContravariantLifetime::<'a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unsafe vector operations.
|
/// Unsafe vector operations.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
@ -2169,10 +2202,38 @@ mod tests {
|
|||||||
use std::prelude::*;
|
use std::prelude::*;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
use super::{unzip, raw, Vec};
|
use super::{as_vec, unzip, raw, Vec};
|
||||||
|
|
||||||
use MutableSeq;
|
use MutableSeq;
|
||||||
|
|
||||||
|
struct DropCounter<'a> {
|
||||||
|
count: &'a mut int
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe_destructor]
|
||||||
|
impl<'a> Drop for DropCounter<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
*self.count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_as_vec() {
|
||||||
|
let xs = [1u8, 2u8, 3u8];
|
||||||
|
assert_eq!(as_vec(xs).as_slice(), xs.as_slice());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_as_vec_dtor() {
|
||||||
|
let (mut count_x, mut count_y) = (0, 0);
|
||||||
|
{
|
||||||
|
let xs = &[DropCounter { count: &mut count_x }, DropCounter { count: &mut count_y }];
|
||||||
|
assert_eq!(as_vec(xs).len(), 2);
|
||||||
|
}
|
||||||
|
assert_eq!(count_x, 1);
|
||||||
|
assert_eq!(count_y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_small_vec_struct() {
|
fn test_small_vec_struct() {
|
||||||
assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
|
assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
|
||||||
@ -2185,17 +2246,6 @@ mod tests {
|
|||||||
y: Vec<T>
|
y: Vec<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DropCounter<'a> {
|
|
||||||
count: &'a mut int
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe_destructor]
|
|
||||||
impl<'a> Drop for DropCounter<'a> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
*self.count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mut count_x, mut count_y) = (0, 0);
|
let (mut count_x, mut count_y) = (0, 0);
|
||||||
{
|
{
|
||||||
let mut tv = TwoVec {
|
let mut tv = TwoVec {
|
||||||
|
Loading…
Reference in New Issue
Block a user