Skip to content

Commit 38e25ea

Browse files
committed
Add VecRef to std::vec
This adds a `VecRef` that can hold either a ~[T] or a &'static [T]
1 parent e89dcb8 commit 38e25ea

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

src/libstd/vec.rs

+216
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,171 @@ impl<'self, T:Clone> MutableCloneableVector<T> for &'self mut [T] {
17271727
}
17281728
}
17291729

1730+
/**
1731+
* A VecRef is a vector that can hold either an owned vector,
1732+
* ~[T] or a static slice, &'static [T]. This can be useful as
1733+
* an optimization when allocation is sometimes needed, but the
1734+
* common case is statically known.
1735+
*/
1736+
#[deriving(Eq,Ord,Clone)]
1737+
pub enum VecRef<T> {
1738+
Own(~[T]),
1739+
Static(&'static [T])
1740+
}
1741+
1742+
impl<T> VecRef<T> {
1743+
/**
1744+
* Construct a VecRef from an owned vector
1745+
*/
1746+
pub fn from_owned(val: ~[T]) -> VecRef<T> {
1747+
Own(val)
1748+
}
1749+
1750+
/**
1751+
* Construct a VecRef from a static vector
1752+
*/
1753+
pub fn from_static(val: &'static [T]) -> VecRef<T> {
1754+
Static(val)
1755+
}
1756+
1757+
// I can't impl ImmutableVector because that has methods
1758+
// on self-by-value, which means VecRef would move into
1759+
// it. So I'm just gonna re-impl here
1760+
1761+
#[inline]
1762+
pub fn iter<'r>(&'r self) -> VecIterator<'r, T> {
1763+
self.as_slice().iter()
1764+
}
1765+
1766+
#[inline]
1767+
pub fn rev_iter<'r>(&'r self) -> VecRevIterator<'r, T> {
1768+
self.as_slice().rev_iter()
1769+
}
1770+
1771+
#[inline]
1772+
pub fn split_iter<'r>(&'r self, pred: &'r fn(&T) -> bool) -> VecSplitIterator<'r, T> {
1773+
self.as_slice().split_iter(pred)
1774+
}
1775+
1776+
#[inline]
1777+
pub fn splitn_iter<'r>(&'r self, n: uint, pred: &'r fn(&T) -> bool) -> VecSplitIterator<'r, T> {
1778+
self.as_slice().split_iter(n, pred)
1779+
}
1780+
1781+
#[inline]
1782+
pub fn rsplit_iter<'r>(&'r self, pred: &'r fn(&T) -> bool) -> VecRSplitIterator<'r, T> {
1783+
self.as_slice().rsplit_iter(pred)
1784+
}
1785+
1786+
#[inline]
1787+
pub fn rsplitn_iter<'r>(&'r self, pred: &'r fn(&T) -> bool) -> VecRSplitIterator<'r, T> {
1788+
self.as_slice().rsplit_iter(pred)
1789+
}
1790+
1791+
#[inline]
1792+
pub fn window_iter<'r>(&'r self, size: uint) -> VecWindowIter<'r, T> {
1793+
self.as_slice().window_iter(size)
1794+
}
1795+
1796+
#[inline]
1797+
pub fn chunk_iter<'r>(&'r self, size: uint) -> VecChunkIter<'r, T> {
1798+
self.as_slice().window_iter(size)
1799+
}
1800+
1801+
#[inline]
1802+
pub fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
1803+
self.as_slice().as_imm_buf(f)
1804+
}
1805+
}
1806+
1807+
impl<T:Copy> VecRef<T> {
1808+
1809+
/**
1810+
* Converts this type into a standard owned vector, consuming it in the process.
1811+
*
1812+
* If the VecRef holds a static vector, it is converted to an owned one, otherwise the held
1813+
* owned vector is returned.
1814+
*/
1815+
pub fn to_owned_consume(self) -> ~[T] {
1816+
match self {
1817+
Own(v) => v,
1818+
Static(v) => v.to_owned()
1819+
}
1820+
}
1821+
1822+
}
1823+
1824+
impl<T> Vector<T> for VecRef<T> {
1825+
#[inline(always)]
1826+
fn as_slice<'a>(&'a self) -> &'a [T] {
1827+
match *self {
1828+
Own(ref v) => v.as_slice(),
1829+
Static(slice) => slice
1830+
}
1831+
}
1832+
}
1833+
1834+
impl<T> Container for VecRef<T> {
1835+
#[inline]
1836+
fn is_empty(&self) -> bool {
1837+
self.as_slice().is_empty()
1838+
}
1839+
1840+
#[inline]
1841+
fn len(&self) -> uint {
1842+
self.as_slice().len()
1843+
}
1844+
}
1845+
1846+
impl<T:Copy> CopyableVector<T> for VecRef<T> {
1847+
#[inline]
1848+
fn to_owned(&self) -> ~[T] {
1849+
self.as_slice().to_owned()
1850+
}
1851+
}
1852+
1853+
impl<T:Eq> ImmutableEqVector<T> for VecRef<T> {
1854+
#[inline]
1855+
fn position_elem(&self, x: &T) -> Option<uint> {
1856+
self.as_slice().position_elem(x)
1857+
}
1858+
1859+
#[inline]
1860+
fn rposition_elem(&self, t: &T) -> Option<uint> {
1861+
self.as_slice().rposition(t)
1862+
}
1863+
1864+
#[inline]
1865+
fn contains(&self, x: &T) -> bool {
1866+
self.as_slice().contains(x)
1867+
}
1868+
}
1869+
1870+
impl<T: TotalOrd> ImmutableTotalOrdVector<T> for VecRef<T> {
1871+
#[inline]
1872+
fn bsearch_elem(&self, x: &T) -> Option<uint> {
1873+
self.as_slice().bsearch_elem(x)
1874+
}
1875+
}
1876+
1877+
impl<T:Copy> ImmutableCopyableVector<T> for VecRef<T> {
1878+
#[inline]
1879+
fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) {
1880+
self.as_slice().partitioned(f)
1881+
}
1882+
1883+
#[inline]
1884+
unsafe fn unsafe_get(&self, elem: uint) -> T {
1885+
self.as_slice().unsafe_get(elem)
1886+
}
1887+
}
1888+
1889+
impl<T:Copy> Index<uint, T> for VecRef<T> {
1890+
fn index(&self, index: uint) -> T {
1891+
copy self.as_slice()[index]
1892+
}
1893+
}
1894+
17301895
/**
17311896
* Constructs a vector from an unsafe pointer to a buffer
17321897
*
@@ -2140,6 +2305,31 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
21402305
}
21412306
}
21422307

2308+
#[cfg(stage0)]
2309+
impl<A, T: Iterator<A>> FromIterator<A, T> for VecRef<A> {
2310+
pub fn from_iterator(iterator: &mut T) -> VecRef<A> {
2311+
let mut xs = ~[];
2312+
for iterator.advance |x| {
2313+
xs.push(x);
2314+
}
2315+
VecRef::from_owned(xs)
2316+
}
2317+
}
2318+
2319+
2320+
#[cfg(not(stage0))]
2321+
impl<A, T: Iterator<A>> FromIterator<A, T> for VecRef<A> {
2322+
pub fn from_iterator(iterator: &mut T) -> VecRef<A> {
2323+
let (lower, _) = iterator.size_hint();
2324+
let mut xs = with_capacity(lower.get_or_zero());
2325+
for iterator.advance |x| {
2326+
xs.push(x);
2327+
}
2328+
VecRef::from_owned(xs)
2329+
}
2330+
}
2331+
2332+
21432333

21442334
#[cfg(test)]
21452335
mod tests {
@@ -3244,4 +3434,30 @@ mod tests {
32443434
values.mut_slice(2,4).set_memory(0xFF);
32453435
assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
32463436
}
3437+
3438+
#[test]
3439+
fn test_vec_ref() {
3440+
let v : VecRef<int> = VecRef::from_owned(~[]);
3441+
assert!(v.is_empty());
3442+
3443+
let v = VecRef::from_owned(~[1, 2, 3]);
3444+
assert_eq!(v.len(), 3);
3445+
3446+
let v : VecRef<int> = VecRef::from_static([]);
3447+
assert!(v.is_empty());
3448+
3449+
let v : VecRef<int> = VecRef::from_static([1, 2, 3, 4]);
3450+
assert_eq!(v.len(), 4);
3451+
}
3452+
3453+
#[test]
3454+
fn test_vec_ref_consume() {
3455+
let v = VecRef::from_owned(~[1, 2, 3, 4]);
3456+
let vec = v.to_owned_consume();
3457+
assert_eq!(vec, ~[1, 2, 3, 4]);
3458+
3459+
let v = VecRef::from_static([1, 2, 3, 4]);
3460+
let vec = v.to_owned_consume();
3461+
assert_eq!(vec, ~[1, 2, 3, 4]);
3462+
}
32473463
}

0 commit comments

Comments
 (0)