Skip to content

Commit adc6484

Browse files
committed
Add ArrayVecCopy, which is a copyable ArrayVec
Fixes bluss#32.
1 parent 2c060bd commit adc6484

File tree

4 files changed

+391
-7
lines changed

4 files changed

+391
-7
lines changed

src/copy.rs

+377
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
use std::cmp;
2+
use std::iter;
3+
use std::ptr;
4+
use std::ops;
5+
use std::slice;
6+
7+
// extra traits
8+
use std::borrow::{Borrow, BorrowMut};
9+
use std::hash::{Hash, Hasher};
10+
use std::fmt;
11+
12+
#[cfg(feature="std")]
13+
use std::io;
14+
15+
use Array;
16+
use CapacityError;
17+
use RangeArgument;
18+
use array::Index;
19+
use raw::Drain;
20+
use raw::RawArrayVec;
21+
22+
/// A vector with a fixed capacity that implements `Copy`.
23+
pub struct ArrayVecCopy<A: Array + Copy> {
24+
inner: RawArrayVec<A>,
25+
}
26+
27+
impl<A: Array + Copy> ArrayVecCopy<A> {
28+
/// Create a new empty `ArrayVecCopy`.
29+
///
30+
/// Capacity is inferred from the type parameter.
31+
#[inline]
32+
pub fn new() -> ArrayVecCopy<A> {
33+
ArrayVecCopy {
34+
inner: RawArrayVec::new(),
35+
}
36+
}
37+
38+
/// Return the number of elements in the `ArrayVecCopy`.
39+
#[inline]
40+
pub fn len(&self) -> usize { self.inner.len() }
41+
42+
/// Return the capacity of the `ArrayVecCopy`.
43+
#[inline]
44+
pub fn capacity(&self) -> usize { self.inner.capacity() }
45+
46+
/// Push `element` to the end of the vector.
47+
///
48+
/// Returns `Ok` if the push succeeds.
49+
///
50+
/// **Errors** if the backing array is not large enough to fit the
51+
/// additional element.
52+
#[inline]
53+
pub fn push(&mut self, element: A::Item) -> Result<(), CapacityError<A::Item>> {
54+
self.inner.push(element)
55+
}
56+
57+
/// Insert `element` in position `index`.
58+
///
59+
/// Shift up all elements after `index`. If any is pushed out, `Err` is
60+
/// returned.
61+
///
62+
/// Return `Ok` if no element is shifted out.
63+
#[inline]
64+
pub fn insert(&mut self, index: usize, element: A::Item)
65+
-> Result<(), CapacityError<A::Item>>
66+
{
67+
self.inner.insert(index, element)
68+
}
69+
70+
/// Remove the last element in the vector.
71+
///
72+
/// Return `Some(` *element* `)` if the vector is non-empty, else `None`.
73+
#[inline]
74+
pub fn pop(&mut self) -> Option<A::Item> {
75+
self.inner.pop()
76+
}
77+
78+
/// Remove the element at `index` and swap the last element into its place.
79+
///
80+
/// This operation is O(1).
81+
///
82+
/// Return `Some(` *element* `)` if the index is in bounds, else `None`.
83+
#[inline]
84+
pub fn swap_remove(&mut self, index: usize) -> Option<A::Item> {
85+
self.inner.swap_remove(index)
86+
}
87+
88+
/// Remove the element at `index` and shift down the following elements.
89+
///
90+
/// Return `Some(` *element* `)` if the index is in bounds, else `None`.
91+
#[inline]
92+
pub fn remove(&mut self, index: usize) -> Option<A::Item> {
93+
self.inner.remove(index)
94+
}
95+
96+
/// Remove all elements in the vector.
97+
///
98+
/// This is a constant-time operation.
99+
#[inline]
100+
pub fn clear(&mut self) {
101+
unsafe {
102+
self.set_len(0);
103+
}
104+
}
105+
106+
/// Retains only the elements specified by the predicate.
107+
///
108+
/// In other words, remove all elements `e` such that `f(&mut e)` returns false.
109+
/// This method operates in place and preserves the order of the retained
110+
/// elements.
111+
#[inline]
112+
pub fn retain<F>(&mut self, f: F)
113+
where F: FnMut(&mut A::Item) -> bool
114+
{
115+
self.inner.retain(f)
116+
}
117+
118+
/// Set the vector's length without dropping or moving out elements
119+
///
120+
/// May panic if `length` is greater than the capacity.
121+
///
122+
/// This function is `unsafe` because it changes the notion of the
123+
/// number of “valid” elements in the vector. Use with care.
124+
#[inline]
125+
pub unsafe fn set_len(&mut self, length: usize) {
126+
self.inner.set_len(length)
127+
}
128+
129+
130+
/// Create a draining iterator that removes the specified range in the vector
131+
/// and yields the removed items from start to end. The element range is
132+
/// removed even if the iterator is not consumed until the end.
133+
///
134+
/// Note: It is unspecified how many elements are removed from the vector,
135+
/// if the `Drain` value is leaked.
136+
///
137+
/// **Panics** if the starting point is greater than the end point or if
138+
/// the end point is greater than the length of the vector.
139+
pub fn drain<R: RangeArgument>(&mut self, range: R) -> Drain<A> {
140+
self.inner.drain(range)
141+
}
142+
143+
/// Return the inner fixed size array, if it is full to its capacity.
144+
///
145+
/// Return an `Ok` value with the array if length equals capacity,
146+
/// return an `Err` with self otherwise.
147+
///
148+
/// `Note:` This function may incur unproportionally large overhead
149+
/// to move the array out, its performance is not optimal.
150+
pub fn into_inner(self) -> Result<A, Self> {
151+
self.inner.into_inner().map_err(|e| ArrayVecCopy { inner: e })
152+
}
153+
154+
/// Dispose of `self` without the overwriting that is needed in Drop.
155+
pub fn dispose(self) { }
156+
157+
/// Return a slice containing all elements of the vector.
158+
pub fn as_slice(&self) -> &[A::Item] {
159+
self.inner.as_slice()
160+
}
161+
162+
/// Return a mutable slice containing all elements of the vector.
163+
pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
164+
self.inner.as_mut_slice()
165+
}
166+
}
167+
168+
impl<A: Array + Copy> ops::Deref for ArrayVecCopy<A> {
169+
type Target = [A::Item];
170+
#[inline]
171+
fn deref(&self) -> &[A::Item] {
172+
self.inner.deref()
173+
}
174+
}
175+
176+
impl<A: Array + Copy> ops::DerefMut for ArrayVecCopy<A> {
177+
#[inline]
178+
fn deref_mut(&mut self) -> &mut [A::Item] {
179+
self.inner.deref_mut()
180+
}
181+
}
182+
183+
/// Create an `ArrayVecCopy` from an array.
184+
impl<A: Array + Copy> From<A> for ArrayVecCopy<A> {
185+
fn from(array: A) -> Self {
186+
ArrayVecCopy { inner: RawArrayVec::from(array) }
187+
}
188+
}
189+
190+
191+
/// Iterate the `ArrayVecCopy` with references to each element.
192+
impl<'a, A: Array + Copy> IntoIterator for &'a ArrayVecCopy<A> {
193+
type Item = &'a A::Item;
194+
type IntoIter = slice::Iter<'a, A::Item>;
195+
fn into_iter(self) -> Self::IntoIter { self.inner.iter() }
196+
}
197+
198+
/// Iterate the `ArrayVecCopy` with mutable references to each element.
199+
impl<'a, A: Array + Copy> IntoIterator for &'a mut ArrayVecCopy<A> {
200+
type Item = &'a mut A::Item;
201+
type IntoIter = slice::IterMut<'a, A::Item>;
202+
fn into_iter(self) -> Self::IntoIter { self.inner.iter_mut() }
203+
}
204+
205+
/// Iterate the `ArrayVecCopy` with each element by value.
206+
///
207+
/// The vector is consumed by this operation.
208+
impl<A: Array + Copy> IntoIterator for ArrayVecCopy<A> {
209+
type Item = A::Item;
210+
type IntoIter = IntoIter<A>;
211+
fn into_iter(self) -> IntoIter<A> {
212+
IntoIter { index: Index::from(0), v: self }
213+
}
214+
}
215+
216+
217+
/// By-value iterator for `ArrayVecCopy`.
218+
pub struct IntoIter<A: Array + Copy> {
219+
index: A::Index,
220+
v: ArrayVecCopy<A>,
221+
}
222+
223+
impl<A: Array + Copy> Iterator for IntoIter<A> {
224+
type Item = A::Item;
225+
226+
#[inline]
227+
fn next(&mut self) -> Option<A::Item> {
228+
let index = self.index.to_usize();
229+
if index == self.v.len() {
230+
None
231+
} else {
232+
unsafe {
233+
self.index = Index::from(index + 1);
234+
Some(ptr::read(self.v.get_unchecked_mut(index)))
235+
}
236+
}
237+
}
238+
239+
#[inline]
240+
fn size_hint(&self) -> (usize, Option<usize>) {
241+
let len = self.v.len() - self.index.to_usize();
242+
(len, Some(len))
243+
}
244+
}
245+
246+
impl<A: Array + Copy> DoubleEndedIterator for IntoIter<A> {
247+
#[inline]
248+
fn next_back(&mut self) -> Option<A::Item> {
249+
if self.index.to_usize() == self.v.len() {
250+
None
251+
} else {
252+
unsafe {
253+
let new_len = self.v.len() - 1;
254+
self.v.set_len(new_len);
255+
Some(ptr::read(self.v.get_unchecked_mut(new_len)))
256+
}
257+
}
258+
}
259+
}
260+
261+
impl<A: Array + Copy> ExactSizeIterator for IntoIter<A> { }
262+
263+
/// Extend the `ArrayVecCopy` with an iterator.
264+
///
265+
/// Does not extract more items than there is space for. No error
266+
/// occurs if there are more iterator elements.
267+
impl<A: Array + Copy> Extend<A::Item> for ArrayVecCopy<A> {
268+
fn extend<T: IntoIterator<Item=A::Item>>(&mut self, iter: T) {
269+
self.inner.extend(iter)
270+
}
271+
}
272+
273+
/// Create an `ArrayVecCopy` from an iterator.
274+
///
275+
/// Does not extract more items than there is space for. No error
276+
/// occurs if there are more iterator elements.
277+
impl<A: Array + Copy> iter::FromIterator<A::Item> for ArrayVecCopy<A> {
278+
fn from_iter<T: IntoIterator<Item=A::Item>>(iter: T) -> Self {
279+
ArrayVecCopy { inner: RawArrayVec::from_iter(iter) }
280+
}
281+
}
282+
283+
impl<A: Array + Copy> Clone for ArrayVecCopy<A>
284+
where A::Item: Clone
285+
{
286+
#[inline]
287+
fn clone(&self) -> Self {
288+
ArrayVecCopy { inner: self.inner.clone() }
289+
}
290+
291+
#[inline]
292+
fn clone_from(&mut self, rhs: &Self) {
293+
self.inner.clone_from(&rhs.inner)
294+
}
295+
}
296+
297+
impl<A: Array + Copy> Hash for ArrayVecCopy<A>
298+
where A::Item: Hash
299+
{
300+
fn hash<H: Hasher>(&self, state: &mut H) {
301+
self.inner.hash(state)
302+
}
303+
}
304+
305+
impl<A: Array + Copy> PartialEq for ArrayVecCopy<A>
306+
where A::Item: PartialEq
307+
{
308+
fn eq(&self, other: &Self) -> bool {
309+
use std::ops::Deref;
310+
self.inner.eq(other.inner.deref())
311+
}
312+
}
313+
314+
impl<A: Array + Copy> PartialEq<[A::Item]> for ArrayVecCopy<A>
315+
where A::Item: PartialEq
316+
{
317+
fn eq(&self, other: &[A::Item]) -> bool {
318+
self.inner.eq(other)
319+
}
320+
}
321+
322+
impl<A: Array + Copy> Eq for ArrayVecCopy<A> where A::Item: Eq { }
323+
324+
impl<A: Array + Copy> Borrow<[A::Item]> for ArrayVecCopy<A> {
325+
fn borrow(&self) -> &[A::Item] { self.inner.borrow() }
326+
}
327+
328+
impl<A: Array + Copy> BorrowMut<[A::Item]> for ArrayVecCopy<A> {
329+
fn borrow_mut(&mut self) -> &mut [A::Item] { self.inner.borrow_mut() }
330+
}
331+
332+
impl<A: Array + Copy> AsRef<[A::Item]> for ArrayVecCopy<A> {
333+
fn as_ref(&self) -> &[A::Item] { self.inner.as_ref() }
334+
}
335+
336+
impl<A: Array + Copy> AsMut<[A::Item]> for ArrayVecCopy<A> {
337+
fn as_mut(&mut self) -> &mut [A::Item] { self.inner.as_mut() }
338+
}
339+
340+
impl<A: Array + Copy> fmt::Debug for ArrayVecCopy<A> where A::Item: fmt::Debug {
341+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.fmt(f) }
342+
}
343+
344+
impl<A: Array + Copy> Default for ArrayVecCopy<A> {
345+
fn default() -> ArrayVecCopy<A> {
346+
ArrayVecCopy::new()
347+
}
348+
}
349+
350+
impl<A: Array + Copy> PartialOrd for ArrayVecCopy<A> where A::Item: PartialOrd {
351+
#[inline]
352+
fn partial_cmp(&self, other: &ArrayVecCopy<A>) -> Option<cmp::Ordering> {
353+
self.inner.partial_cmp(&other.inner)
354+
}
355+
356+
#[inline] fn lt(&self, other: &Self) -> bool { self.inner.lt(&other.inner) }
357+
#[inline] fn le(&self, other: &Self) -> bool { self.inner.le(&other.inner) }
358+
#[inline] fn ge(&self, other: &Self) -> bool { self.inner.ge(&other.inner) }
359+
#[inline] fn gt(&self, other: &Self) -> bool { self.inner.gt(&other.inner) }
360+
}
361+
362+
impl<A: Array + Copy> Ord for ArrayVecCopy<A> where A::Item: Ord {
363+
fn cmp(&self, other: &ArrayVecCopy<A>) -> cmp::Ordering {
364+
self.inner.cmp(&other.inner)
365+
}
366+
}
367+
368+
#[cfg(feature="std")]
369+
/// `Write` appends written data to the end of the vector.
370+
///
371+
/// Requires `features="std"`.
372+
impl<A: Array<Item=u8> + Copy> io::Write for ArrayVecCopy<A> {
373+
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
374+
self.inner.write(data)
375+
}
376+
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
377+
}

src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! **arrayvec** provides the types `ArrayVec` and `ArrayString`:
1+
//! **arrayvec** provides the types `ArrayVec` and `ArrayString`:
22
//! array-backed vector and string types, which store their contents inline.
33
//!
44
//! The **arrayvec** crate has the following cargo feature flags:
@@ -16,11 +16,15 @@ extern crate nodrop;
1616
extern crate core as std;
1717

1818
pub use array::Array;
19+
pub use copy::ArrayVecCopy;
1920
pub use odds::IndexRange as RangeArgument;
21+
pub use raw::Drain;
2022
pub use string::ArrayString;
2123
pub use vec::ArrayVec;
24+
pub use vec::IntoIter;
2225

2326
mod array;
27+
mod copy;
2428
mod raw;
2529
mod string;
2630
mod vec;

0 commit comments

Comments
 (0)