fixedvec/lib.rs
1// The MIT License (MIT)
2//
3// Copyright (c) 2015-2016 Nick Stevens <nick@bitcurry.com>
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22//
23// Portions of this work are based on the Rust standard library implementation
24// of Vec: https://github.com/rust-lang/rust/blob/master/src/libcollections/vec.rs
25
26#![crate_type = "lib"]
27#![crate_name = "fixedvec"]
28#![no_std]
29
30//! Heapless Vec implementation using only libcore
31//!
32//! When developing for certain types of systems, especially embedded systems,
33//! it is desirable to avoid the non-determinism that can be introduced by
34//! using a heap. A commonly used data structure is a "buffer" - a
35//! preallocated chunk of memory, either in static memory or on the stack.
36//!
37//! Thanks to the extensibility of Rust, it is possible to have a datatype
38//! that performs _almost_ like the libstd `Vec` type, without requiring a
39//! heap and while only using libcore.
40//!
41//! # Differences from `std::vec::Vec`
42//!
43//! For now, `FixedVec` only works for types that implement `Copy`. This
44//! requirement will be lifted in the future, but for now it is the most
45//! straightforward way to get to a minimum viable product.
46//!
47//! Although every effort has been made to mimic the functionality of `Vec`,
48//! this is not a perfect clone. Specifically, functions that require memory
49//! allocation are not included. There are also a few functions where the type
50//! signatures are different - usually to add a `Result` that indicates whether
51//! or not adding an element was successful.
52//!
53//! Note that the `Vec` functionality of panicking when an invalid index is
54//! accessed has been preserved. Note that this is true _even if the index is
55//! valid for the underlying memory_. So, for example, if a `FixedVec` were
56//! allocated with 10 elements, and 3 new elements were pushed to it, accessing
57//! index 5 would panic, even though accessing that memory would be safe.
58//!
59//! ## Functions with different signatures
60//!
61//! The following functions have different signatures than their equivalents in
62//! `Vec`.
63//!
64//! * `new`: Self-explanatory - instantiating a different object
65//! * `push`, `push_all`, `insert`: Functions that add elements return a Result
66//! indicating if the result was successful.
67//! * `map_in_place`: Similar to `Vec` `map_in_place`, except there is no
68//! coercion of the types.
69//!
70//! ## Functions in `FixedVec` not in `Vec`
71//!
72//! * `available`: Convenience function for checking remaining space.
73//! * `iter`: `FixedVec` cannot implement `IntoIterator` because the type
74//! signature of that trait requires taking ownership of the underlying
75//! struct. Since `FixedVec` keeps a reference to its backing store,
76//! ownership is not its to give. It's possible I'm just being dense and this
77//! is possible - I'd love to be proven wrong.
78//!
79//! ## Functions in `Vec` excluded from `FixedVec`
80//!
81//! The following `Vec` functions do not exist in `FixedVec` because they deal
82//! with allocating or reserving memory - a step that is done up-front in
83//! `FixedVec`.
84//!
85//! * `with_capacity`
86//! * `from_raw_parts`
87//! * `from_raw_buffer`
88//! * `reserve`
89//! * `reserve_exact`
90//! * `shrink_to_fit`
91//! * `into_boxed_slice`
92//! * `truncate`
93//! * `set_len`
94//! * `append`
95//! * `drain`
96//! * `split_off`
97//!
98//! # Example
99//!
100//! Typical usage looks like the following:
101//!
102//! ```
103//! // Pull in fixedvec
104//! #[macro_use]
105//! extern crate fixedvec;
106//!
107//! use fixedvec::FixedVec;
108//!
109//! fn main() {
110//! let mut preallocated_space = alloc_stack!([u8; 10]);
111//! let mut vec = FixedVec::new(&mut preallocated_space);
112//! assert_eq!(vec.len(), 0);
113//!
114//! vec.push_all(&[1, 2, 3]).unwrap();
115//! assert_eq!(vec.len(), 3);
116//! assert_eq!(vec[1], 2);
117//!
118//! vec[1] = 5;
119//! assert_eq!(vec[1], 5);
120//! }
121//! ```
122//!
123//! If you're building for an embedded system, you will want to refer to the
124//! Rust book section ["No stdlib"](https://doc.rust-lang.org/book/no-stdlib.html)
125//! for instructions on building executables using only libcore.
126
127use core::hash::{Hash, Hasher};
128use core::ops;
129
130#[cfg(test)]
131#[macro_use]
132extern crate std;
133
134/// Convenience macro for use with `FixedVec`. Allocates the specified number
135/// of elements of specified type on the stack.
136///
137/// # Example
138///
139/// ```
140/// # #[macro_use] extern crate fixedvec;
141/// # use fixedvec::FixedVec;
142/// # fn main() {
143/// // Allocate space for 16 u8's
144/// let mut space = alloc_stack!([u8; 16]);
145///
146/// // Give the space to a `FixedVec`, which manages it from here on out
147/// let vec = FixedVec::new(&mut space);
148/// # }
149/// ```
150#[macro_export]
151macro_rules! alloc_stack {
152 ([$item_type:ty; $len:expr]) => {{
153 let space: [$item_type; $len] = [Default::default(); $len];
154 space
155 }};
156}
157
158pub type Result<T> = core::result::Result<T, ErrorKind>;
159
160#[derive(Debug)]
161pub enum ErrorKind {
162 NoSpace,
163}
164
165#[derive(Debug)]
166pub struct FixedVec<'a, T: 'a + Copy> {
167 memory: &'a mut [T],
168 len: usize,
169}
170
171pub use core::slice::Iter;
172pub use core::slice::IterMut;
173
174impl<'a, T> FixedVec<'a, T>
175where
176 T: 'a + Copy,
177{
178 /// Create a new `FixedVec` from the provided slice, in the process taking
179 /// ownership of the slice.
180 ///
181 /// # Example
182 ///
183 /// ```
184 /// # #[macro_use] extern crate fixedvec;
185 /// # use fixedvec::FixedVec;
186 /// # fn main() {
187 /// let mut space = alloc_stack!([u8; 16]);
188 /// let vec = FixedVec::new(&mut space);
189 /// assert_eq!(vec.capacity(), 16);
190 /// assert_eq!(vec.len(), 0);
191 /// assert_eq!(&[] as &[u8], vec.as_slice());
192 /// # }
193 /// ```
194 ///
195 pub fn new(memory: &'a mut [T]) -> Self {
196 FixedVec {
197 memory: memory,
198 len: 0,
199 }
200 }
201
202 /// Returns the capacity of the vector.
203 ///
204 /// # Example
205 ///
206 /// ```
207 /// # #[macro_use] extern crate fixedvec;
208 /// # use fixedvec::FixedVec;
209 /// # fn main() {
210 /// let mut space = alloc_stack!([u8; 16]);
211 /// let mut vec = FixedVec::new(&mut space);
212 /// assert_eq!(vec.capacity(), 16);
213 /// vec.push(1).unwrap();
214 /// assert_eq!(vec.capacity(), 16);
215 /// # }
216 /// ```
217 #[inline]
218 pub fn capacity(&self) -> usize {
219 self.memory.len()
220 }
221
222 /// Returns the number of elements in the vector. This will always be
223 /// less than or equal to the `capacity()`.
224 ///
225 /// # Example
226 ///
227 /// ```
228 /// # #[macro_use] extern crate fixedvec;
229 /// # use fixedvec::FixedVec;
230 /// # fn main() {
231 /// let mut space = alloc_stack!([u8; 16]);
232 /// let mut vec = FixedVec::new(&mut space);
233 /// vec.push(1).unwrap();
234 /// vec.push(2).unwrap();
235 /// assert_eq!(vec.len(), 2);
236 /// # }
237 /// ```
238 #[inline]
239 pub fn len(&self) -> usize {
240 self.len
241 }
242
243 /// Returns the number of available elements in the vector. Adding more
244 /// than this number of elements (without removing some elements) will
245 /// cause further calls to element-adding functions to fail.
246 ///
247 /// # Example
248 ///
249 /// ```
250 /// # #[macro_use] extern crate fixedvec;
251 /// # use fixedvec::FixedVec;
252 /// # fn main() {
253 /// let mut space = alloc_stack!([u8; 16]);
254 /// let mut vec = FixedVec::new(&mut space);
255 /// assert_eq!(vec.available(), 16);
256 /// vec.push(1).unwrap();
257 /// assert_eq!(vec.available(), 15);
258 /// assert_eq!(vec.available(), vec.capacity() - vec.len());
259 /// # }
260 /// ```
261 #[inline]
262 pub fn available(&self) -> usize {
263 self.capacity() - self.len()
264 }
265
266 /// Returns `true` if the vector contains no elements.
267 ///
268 /// # Example
269 ///
270 /// ```
271 /// # #[macro_use] extern crate fixedvec;
272 /// # use fixedvec::FixedVec;
273 /// # fn main() {
274 /// let mut space = alloc_stack!([u8; 16]);
275 /// let mut vec = FixedVec::new(&mut space);
276 /// assert!(vec.is_empty());
277 /// vec.push(1);
278 /// assert!(!vec.is_empty());
279 /// # }
280 #[inline]
281 pub fn is_empty(&self) -> bool {
282 self.len == 0
283 }
284
285 /// Extracts a slice containing the entire vector.
286 ///
287 /// Equivalent to `&s[..]`.
288 ///
289 /// # Example
290 ///
291 /// ```
292 /// # #[macro_use] extern crate fixedvec;
293 /// # use fixedvec::FixedVec;
294 /// # fn main() {
295 /// let mut space = alloc_stack!([u8; 16]);
296 /// let mut vec = FixedVec::new(&mut space);
297 ///
298 /// vec.push_all(&[1, 2, 3, 4]).unwrap();
299 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
300 /// # }
301 #[inline]
302 pub fn as_slice(&self) -> &[T] {
303 &self.memory[..self.len]
304 }
305
306 /// Extracts a mutable slice of the entire vector.
307 ///
308 /// Equivalent to `&mut s[..]`.
309 ///
310 /// # Example
311 ///
312 /// ```
313 /// # #[macro_use] extern crate fixedvec;
314 /// # use fixedvec::FixedVec;
315 /// # fn main() {
316 /// let mut space = alloc_stack!([u8; 16]);
317 /// let mut vec = FixedVec::new(&mut space);
318 ///
319 /// vec.push(1).unwrap();
320 /// let mut slice = vec.as_mut_slice();
321 /// slice[0] = 2;
322 /// assert_eq!(slice[0], 2);
323 /// # }
324 #[inline]
325 pub fn as_mut_slice(&mut self) -> &mut [T] {
326 &mut self.memory[..self.len]
327 }
328
329 /// Inserts an element at position `index` within the vector, shifting all
330 /// elements after position `i` one position to the right.
331 ///
332 /// # Panics
333 ///
334 /// Panics if `index` is greater than the vector's length.
335 ///
336 /// # Example
337 ///
338 /// ```
339 /// # #[macro_use] extern crate fixedvec;
340 /// # use fixedvec::FixedVec;
341 /// # fn main() {
342 /// let mut space = alloc_stack!([u8; 5]);
343 /// let mut vec = FixedVec::new(&mut space);
344 ///
345 /// // Inserting in the middle moves elements to the right
346 /// vec.push_all(&[1, 2, 3]).unwrap();
347 /// vec.insert(1, 15).unwrap();
348 /// assert_eq!(vec.as_slice(), &[1, 15, 2, 3]);
349 ///
350 /// // Can also insert at the end of the vector
351 /// vec.insert(4, 16).unwrap();
352 /// assert_eq!(vec.as_slice(), &[1, 15, 2, 3, 16]);
353 ///
354 /// // Cannot insert if there is not enough capacity
355 /// assert!(vec.insert(2, 17).is_err());
356 /// # }
357 pub fn insert(&mut self, index: usize, element: T) -> Result<()> {
358 assert!(index <= self.len);
359 if index == self.len || self.len == 0 {
360 self.push(element)
361 } else if self.available() >= 1 {
362 self.len += 1;
363 let mut i = self.len;
364 loop {
365 if i == index {
366 break;
367 }
368 self.memory[i] = self.memory[i - 1];
369 i -= 1;
370 }
371 self.memory[index] = element;
372 Ok(())
373 } else {
374 Err(ErrorKind::NoSpace)
375 }
376 }
377
378 /// Removes and returns the element at position `index` within the vector,
379 /// shifting all elements after position `index` one position to the left.
380 ///
381 /// # Panics
382 ///
383 /// Panics if `index` is out of bounds.
384 ///
385 /// # Examples
386 ///
387 /// ```
388 /// # #[macro_use] extern crate fixedvec;
389 /// # use fixedvec::FixedVec;
390 /// # fn main() {
391 /// let mut space = alloc_stack!([u8; 16]);
392 /// let mut vec = FixedVec::new(&mut space);
393 ///
394 /// // Remove element from the middle
395 /// vec.push_all(&[1, 2, 3]).unwrap();
396 /// assert_eq!(vec.remove(1), 2);
397 /// assert_eq!(vec.as_slice(), &[1, 3]);
398 ///
399 /// // Remove element from the end
400 /// assert_eq!(vec.remove(1), 3);
401 /// assert_eq!(vec.as_slice(), &[1]);
402 /// # }
403 pub fn remove(&mut self, index: usize) -> T {
404 assert!(index < self.len);
405 let ret = self.memory[index];
406 self.len -= 1;
407 for i in index..self.len {
408 self.memory[i] = self.memory[i + 1];
409 }
410 ret
411 }
412
413 /// Appends an element to the back of the vector.
414 ///
415 /// # Example
416 ///
417 /// ```
418 /// # #[macro_use] extern crate fixedvec;
419 /// # use fixedvec::FixedVec;
420 /// # fn main() {
421 /// let mut space = alloc_stack!([u8; 3]);
422 /// let mut vec = FixedVec::new(&mut space);
423 ///
424 /// // Pushing appends to the end of the vector
425 /// vec.push(1).unwrap();
426 /// vec.push(2).unwrap();
427 /// vec.push(3).unwrap();
428 /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
429 ///
430 /// // Attempting to push a full vector results in an error
431 /// assert!(vec.push(4).is_err());
432 /// # }
433 /// ```
434 #[inline]
435 pub fn push(&mut self, value: T) -> Result<()> {
436 if self.available() >= 1 {
437 self.memory[self.len] = value;
438 self.len += 1;
439 Ok(())
440 } else {
441 Err(ErrorKind::NoSpace)
442 }
443 }
444
445 /// Removes the last element from the vector and returns it, or `None` if
446 /// the vector is empty
447 ///
448 /// # Example
449 ///
450 /// ```
451 /// # #[macro_use] extern crate fixedvec;
452 /// # use fixedvec::FixedVec;
453 /// # fn main() {
454 /// let mut space = alloc_stack!([u8; 16]);
455 /// let mut vec = FixedVec::new(&mut space);
456 /// vec.push_all(&[1, 2]).unwrap();
457 /// assert_eq!(vec.pop(), Some(2));
458 /// assert_eq!(vec.pop(), Some(1));
459 /// assert_eq!(vec.pop(), None);
460 /// # }
461 /// ```
462 #[inline]
463 pub fn pop(&mut self) -> Option<T> {
464 if self.len > 0 {
465 self.len -= 1;
466 Some(self.memory[self.len])
467 } else {
468 None
469 }
470 }
471
472 /// Copies all elements from slice `other` to this vector.
473 ///
474 /// # Example
475 ///
476 /// ```
477 /// # #[macro_use] extern crate fixedvec;
478 /// # use fixedvec::FixedVec;
479 /// # fn main() {
480 /// let mut space = alloc_stack!([u8; 5]);
481 /// let mut vec = FixedVec::new(&mut space);
482 ///
483 /// // All elements are pushed to vector
484 /// vec.push_all(&[1, 2, 3, 4]).unwrap();
485 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
486 ///
487 /// // If there is insufficient space, NO values are pushed
488 /// assert!(vec.push_all(&[5, 6, 7]).is_err());
489 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
490 /// # }
491 /// ```
492 #[inline]
493 pub fn push_all(&mut self, other: &[T]) -> Result<()> {
494 if other.len() > self.available() {
495 Err(ErrorKind::NoSpace)
496 } else {
497 for item in other.iter() {
498 self.memory[self.len] = *item;
499 self.len += 1;
500 }
501 Ok(())
502 }
503 }
504
505 /// Clears the vector, removing all values.
506 ///
507 /// # Example
508 ///
509 /// ```
510 /// # #[macro_use] extern crate fixedvec;
511 /// # use fixedvec::FixedVec;
512 /// # fn main() {
513 /// let mut space = alloc_stack!([u8; 10]);
514 /// let mut vec = FixedVec::new(&mut space);
515 /// vec.push_all(&[1, 2, 3]).unwrap();
516 /// assert_eq!(vec.len(), 3);
517 /// vec.clear();
518 /// assert_eq!(vec.len(), 0);
519 /// # }
520 /// ```
521 pub fn clear(&mut self) {
522 self.len = 0
523 }
524
525 /// Applies the function `f` to all elements in the vector, mutating the
526 /// vector in place.
527 ///
528 /// # Example
529 ///
530 /// ```
531 /// # #[macro_use] extern crate fixedvec;
532 /// # use fixedvec::FixedVec;
533 /// # fn main() {
534 /// let mut space = alloc_stack!([u8; 10]);
535 /// let mut vec = FixedVec::new(&mut space);
536 ///
537 /// vec.push_all(&[1, 2, 3]).unwrap();
538 /// vec.map_in_place(|x: &mut u8| { *x *= 2 });
539 /// assert_eq!(vec.as_slice(), &[2, 4, 6]);
540 /// # }
541 /// ```
542 pub fn map_in_place<F>(&mut self, f: F)
543 where
544 F: Fn(&mut T),
545 {
546 for i in 0..self.len {
547 f(&mut self.memory[i]);
548 }
549 }
550
551 /// Provides a forward iterator.
552 ///
553 /// # Example
554 ///
555 /// ```
556 /// # #[macro_use] extern crate fixedvec;
557 /// # use fixedvec::FixedVec;
558 /// # fn main() {
559 /// let mut space = alloc_stack!([u8; 10]);
560 /// let mut vec = FixedVec::new(&mut space);
561 /// vec.push_all(&[1, 2, 3]).unwrap();
562 /// {
563 /// let mut iter = vec.iter();
564 /// assert_eq!(iter.next(), Some(&1));
565 /// assert_eq!(iter.next(), Some(&2));
566 /// assert_eq!(iter.next(), Some(&3));
567 /// assert_eq!(iter.next(), None);
568 /// }
569 /// # }
570 /// ```
571 #[inline]
572 pub fn iter(&self) -> Iter<T> {
573 let (slice, _) = self.memory.split_at(self.len);
574 slice.iter()
575 }
576
577 /// Provides a mutable forward iterator.
578 ///
579 /// # Example
580 ///
581 /// ```
582 /// # #[macro_use] extern crate fixedvec;
583 /// # use fixedvec::FixedVec;
584 /// # fn main() {
585 /// let mut space = alloc_stack!([u8; 10]);
586 /// let mut vec = FixedVec::new(&mut space);
587 /// vec.push_all(&[1, 2, 3]).unwrap();
588 /// {
589 /// let mut iter = vec.iter_mut();
590 /// let mut x = iter.next().unwrap();
591 /// *x = 5;
592 /// }
593 /// assert_eq!(vec.as_slice(), &[5, 2, 3]);
594 /// # }
595 /// ```
596 #[inline]
597 pub fn iter_mut(&mut self) -> IterMut<T> {
598 let (slice, _) = self.memory.split_at_mut(self.len);
599 slice.iter_mut()
600 }
601
602 /// Removes an element from anywhere in the vector and returns it,
603 /// replacing it with the last element.
604 ///
605 /// This does not preserve ordering, but is O(1)
606 ///
607 /// # Panics
608 ///
609 /// Panics if `index` is out of bounds
610 ///
611 /// # Example
612 ///
613 /// ```
614 /// # #[macro_use] extern crate fixedvec;
615 /// # use fixedvec::FixedVec;
616 /// # fn main() {
617 /// let mut space = alloc_stack!([u8; 10]);
618 /// let mut vec = FixedVec::new(&mut space);
619 ///
620 /// vec.push_all(&[0, 1, 2, 3]).unwrap();
621 /// assert_eq!(vec.swap_remove(1), 1);
622 /// assert_eq!(vec.as_slice(), &[0, 3, 2]);
623 /// # }
624 /// ```
625 pub fn swap_remove(&mut self, index: usize) -> T {
626 assert!(index < self.len);
627 if self.len == 1 {
628 self.remove(0)
629 } else {
630 let removed = self.memory[index];
631 self.memory[index] = self.pop().unwrap();
632 removed
633 }
634 }
635
636 /// Resizes the vector in-place so that `len()` is equal to `new_len`.
637 ///
638 /// New elements (if needed) are cloned from `value`.
639 ///
640 /// # Panics
641 ///
642 /// Panics if `new_len` is greater than capacity
643 ///
644 /// # Example
645 ///
646 /// ```
647 /// # #[macro_use] extern crate fixedvec;
648 /// # use fixedvec::FixedVec;
649 /// # fn main() {
650 /// let mut space = alloc_stack!([u8; 10]);
651 /// let mut vec = FixedVec::new(&mut space);
652 ///
653 /// assert_eq!(vec.len(), 0);
654 /// vec.resize(5, 255);
655 /// assert_eq!(vec.as_slice(), &[255, 255, 255, 255, 255]);
656 /// vec.resize(2, 0);
657 /// assert_eq!(vec.as_slice(), &[255, 255]);
658 /// # }
659 /// ```
660 pub fn resize(&mut self, new_len: usize, value: T) {
661 assert!(new_len <= self.capacity());
662 if new_len <= self.len {
663 self.len = new_len;
664 } else {
665 for i in self.memory[self.len..new_len].iter_mut() {
666 *i = Clone::clone(&value);
667 }
668 self.len = new_len;
669 }
670 }
671
672 /// Retains only the elements specified by the predicate.
673 ///
674 /// In other words, remove all elements `e` such that `f(&e)` returns
675 /// false. This method operates in-place, in O(N) time, and preserves the
676 /// order of the retained elements.
677 ///
678 /// # Example
679 ///
680 /// ```
681 /// # #[macro_use] extern crate fixedvec;
682 /// # use fixedvec::FixedVec;
683 /// # fn main() {
684 /// let mut space = alloc_stack!([u8; 10]);
685 /// let mut vec = FixedVec::new(&mut space);
686 ///
687 /// vec.push_all(&[1, 2, 3, 4]).unwrap();
688 /// vec.retain(|&x| x%2 == 0);
689 /// assert_eq!(vec.as_slice(), &[2, 4]);
690 /// # }
691 /// ```
692 pub fn retain<F>(&mut self, f: F)
693 where
694 F: Fn(&T) -> bool,
695 {
696 let mut head: usize = 0;
697 let mut tail: usize = 0;
698 loop {
699 if head >= self.len {
700 break;
701 }
702 if f(&self.memory[head]) {
703 self.memory[tail] = self.memory[head];
704 tail += 1;
705 }
706 head += 1;
707 }
708 self.len = tail;
709 }
710
711 /// Returns a reference to the element at the given index, or `None` if the
712 /// index is out of bounds.
713 ///
714 /// # Example
715 ///
716 /// ```
717 /// # #[macro_use] extern crate fixedvec;
718 /// # use fixedvec::FixedVec;
719 /// # fn main() {
720 /// let mut space = alloc_stack!([u8; 10]);
721 /// let mut vec = FixedVec::new(&mut space);
722 ///
723 /// vec.push_all(&[10, 40, 30]).unwrap();
724 /// assert_eq!(Some(&40), vec.get(1));
725 /// assert_eq!(None, vec.get(3));
726 /// # }
727 /// ```
728 pub fn get(&self, index: usize) -> Option<&T> {
729 self.as_slice().get(index)
730 }
731
732 /// Returns a mutable reference to the element at the given index, or
733 /// `None` if the index is out of bounds.
734 ///
735 /// # Example
736 ///
737 /// ```
738 /// # #[macro_use] extern crate fixedvec;
739 /// # use fixedvec::FixedVec;
740 /// # fn main() {
741 /// let mut space = alloc_stack!([u8; 10]);
742 /// let mut vec = FixedVec::new(&mut space);
743 ///
744 /// vec.push_all(&[10, 40, 30]).unwrap();
745 /// {
746 /// let x = vec.get_mut(1).unwrap();
747 /// *x = 50;
748 /// }
749 /// assert_eq!(Some(&50), vec.get(1));
750 /// assert_eq!(None, vec.get(3));
751 /// # }
752 /// ```
753 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
754 self.as_mut_slice().get_mut(index)
755 }
756
757 /// Returns a reference to the element at the given index, without doing
758 /// bounds checking. Note that the result of an invalid index is undefined,
759 /// and may not panic.
760 ///
761 /// # Example
762 ///
763 /// ```
764 /// # #[macro_use] extern crate fixedvec;
765 /// # use fixedvec::FixedVec;
766 /// # fn main() {
767 /// let mut space = alloc_stack!([u8; 10]);
768 /// let mut vec = FixedVec::new(&mut space);
769 ///
770 /// vec.push_all(&[10, 40, 30]).unwrap();
771 /// assert_eq!(&40, unsafe { vec.get_unchecked(1) });
772 ///
773 /// // Index beyond bounds is undefined
774 /// //assert_eq!(None, vec.get(3));
775 /// # }
776 /// ```
777 pub unsafe fn get_unchecked(&self, index: usize) -> &T {
778 self.as_slice().get_unchecked(index)
779 }
780
781 /// Returns a mutable reference to the element at the given index, without
782 /// doing bounds checking. Note that the result of an invalid index is
783 /// undefined, and may not panic.
784 ///
785 /// # Example
786 ///
787 /// ```
788 /// # #[macro_use] extern crate fixedvec;
789 /// # use fixedvec::FixedVec;
790 /// # fn main() {
791 /// let mut space = alloc_stack!([u8; 10]);
792 /// let mut vec = FixedVec::new(&mut space);
793 ///
794 /// vec.push_all(&[10, 40, 30]).unwrap();
795 /// {
796 /// let mut x = unsafe { vec.get_unchecked_mut(1) };
797 /// *x = 50;
798 /// }
799 /// assert_eq!(Some(&50), vec.get(1));
800 ///
801 /// // Index beyond bounds is undefined
802 /// //assert_eq!(None, vec.get(3));
803 /// # }
804 /// ```
805 pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
806 self.as_mut_slice().get_unchecked_mut(index)
807 }
808}
809
810impl<'a, T> FixedVec<'a, T>
811where
812 T: 'a + Copy + PartialEq<T>,
813{
814 /// Removes consecutive repeated elements in the vector in O(N) time.
815 ///
816 /// If the vector is sorted, this removes all duplicates.
817 ///
818 /// # Example
819 ///
820 /// ```
821 /// # #[macro_use] extern crate fixedvec;
822 /// # use fixedvec::FixedVec;
823 /// # fn main() {
824 /// let mut space = alloc_stack!([u8; 10]);
825 /// let mut vec = FixedVec::new(&mut space);
826 /// vec.push_all(&[1, 2, 2, 3, 2]).unwrap();
827 /// vec.dedup();
828 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 2]);
829 /// # }
830 /// ```
831 pub fn dedup(&mut self) {
832 if self.len <= 1 {
833 return;
834 }
835 let mut head: usize = 1;
836 let mut tail: usize = 0;
837 loop {
838 if head >= self.len {
839 break;
840 }
841 if self.memory[head] != self.memory[tail] {
842 tail += 1;
843 self.memory[tail] = self.memory[head];
844 }
845 head += 1;
846 }
847 self.len = tail + 1;
848 }
849}
850
851impl<'a, T: Copy> IntoIterator for &'a FixedVec<'a, T> {
852 type Item = &'a T;
853 type IntoIter = Iter<'a, T>;
854
855 fn into_iter(self) -> Iter<'a, T> {
856 self.iter()
857 }
858}
859
860impl<'a, T: Copy> IntoIterator for &'a mut FixedVec<'a, T> {
861 type Item = &'a mut T;
862 type IntoIter = IterMut<'a, T>;
863
864 fn into_iter(self) -> IterMut<'a, T> {
865 self.iter_mut()
866 }
867}
868
869impl<'a, T> Hash for FixedVec<'a, T>
870where
871 T: Copy + Hash,
872{
873 #[inline]
874 fn hash<H: Hasher>(&self, state: &mut H) {
875 Hash::hash(&*self.memory, state)
876 }
877}
878
879impl<'a, T> Extend<T> for FixedVec<'a, T>
880where
881 T: Copy,
882{
883 fn extend<I: IntoIterator<Item = T>>(&mut self, iterable: I) {
884 if self.available() == 0 {
885 return;
886 }
887 for n in iterable {
888 self.memory[self.len] = n;
889 self.len += 1;
890 if self.available() == 0 {
891 break;
892 }
893 }
894 }
895}
896
897impl<'a, T> ops::Index<usize> for FixedVec<'a, T>
898where
899 T: Copy,
900{
901 type Output = T;
902
903 #[inline]
904 fn index(&self, index: usize) -> &T {
905 &(self.memory)[index]
906 }
907}
908
909impl<'a, T> ops::IndexMut<usize> for FixedVec<'a, T>
910where
911 T: Copy,
912{
913 #[inline]
914 fn index_mut(&mut self, index: usize) -> &mut T {
915 &mut (self.memory)[index]
916 }
917}
918
919impl<'a, T> PartialEq for FixedVec<'a, T>
920where
921 T: Copy + PartialEq,
922{
923 fn eq(&self, other: &FixedVec<'a, T>) -> bool {
924 if self.len() != other.len() {
925 return false;
926 }
927
928 (0..self.len()).all(|i| self[i] == other[i])
929 }
930}
931
932impl<'a, T> Eq for FixedVec<'a, T> where T: Copy + Eq {}
933
934#[cfg(test)]
935mod test {
936 use super::FixedVec;
937 use std::collections::hash_map::DefaultHasher;
938 use std::hash::Hash;
939 use std::prelude::v1::*;
940
941 #[test]
942 fn test_empty_array() {
943 let mut empty = alloc_stack!([u8; 0]);
944 let mut vec = FixedVec::new(&mut empty);
945 assert!(vec.is_empty());
946 assert_eq!(vec.capacity(), 0);
947 assert_eq!(vec.len(), 0);
948 assert_eq!(vec.available(), 0);
949 assert_eq!(vec.as_slice(), &[] as &[u8]);
950 assert!(vec.push(0).is_err());
951 assert!(vec.push_all(&[] as &[u8]).is_ok());
952 assert!(vec.push_all(&[1]).is_err());
953 vec.clear();
954 vec.map_in_place(|x: &mut u8| *x = 1);
955 vec.retain(|_: &u8| true);
956 vec.dedup();
957 {
958 let mut iter = vec.iter();
959 assert!(iter.next().is_none());
960 }
961 }
962
963 #[test]
964 #[should_panic]
965 fn test_insert_bad_index() {
966 let mut space = alloc_stack!([u8; 10]);
967 let mut vec = FixedVec::new(&mut space);
968 vec.insert(3, 0).unwrap();
969 }
970
971 #[test]
972 #[should_panic]
973 fn test_remove_bad_index() {
974 let mut space = alloc_stack!([u8; 10]);
975 let mut vec = FixedVec::new(&mut space);
976 vec.push_all(&[1, 2, 3, 4, 5]).unwrap();
977 vec.remove(8);
978 }
979
980 #[test]
981 #[should_panic]
982 fn test_resize_bad_len() {
983 let mut space = alloc_stack!([u8; 10]);
984 let mut vec = FixedVec::new(&mut space);
985 vec.resize(15, 0);
986 }
987
988 #[test]
989 #[should_panic]
990 fn test_swap_remove_bad_index() {
991 let mut space = alloc_stack!([u8; 10]);
992 let mut vec = FixedVec::new(&mut space);
993 vec.push_all(&[1, 2, 3, 4, 5]).unwrap();
994 vec.swap_remove(8);
995 }
996
997 #[test]
998 fn test_iterator() {
999 let mut space = alloc_stack!([u8; 10]);
1000 let mut vec = FixedVec::new(&mut space);
1001 vec.push_all(&[1, 2, 3, 4, 5]).unwrap();
1002 let result: Vec<u8> = vec.iter().map(|&x| x).collect();
1003 assert_eq!(vec.as_slice(), &result[..]);
1004 }
1005
1006 #[test]
1007 fn test_hash() {
1008 // Two vectors with the same contents should have the same hash
1009 let mut space1 = alloc_stack!([u8; 10]);
1010 let mut vec1 = FixedVec::new(&mut space1);
1011 let mut hasher1 = DefaultHasher::new();
1012 vec1.push_all(&[1, 2, 3, 4, 5]).unwrap();
1013 let mut space2 = alloc_stack!([u8; 10]);
1014 let mut vec2 = FixedVec::new(&mut space2);
1015 let mut hasher2 = DefaultHasher::new();
1016 vec2.push_all(&[1, 2, 3, 4, 5]).unwrap();
1017 assert_eq!(vec1.hash(&mut hasher1), vec2.hash(&mut hasher2));
1018 }
1019
1020 #[test]
1021 fn test_extend() {
1022 let mut space = alloc_stack!([u8; 10]);
1023 let mut vec = FixedVec::new(&mut space);
1024 vec.extend(0..6);
1025 assert_eq!(vec.as_slice(), &[0, 1, 2, 3, 4, 5]);
1026 }
1027
1028 #[test]
1029 fn test_equal() {
1030 let mut space1 = alloc_stack!([u8; 10]);
1031 let mut vec1 = FixedVec::new(&mut space1);
1032 vec1.push_all(&[1, 2, 3, 4, 5]).unwrap();
1033
1034 // Should be equal even if alloc'd space isn't the same
1035 let mut space2 = alloc_stack!([u8; 5]);
1036 let mut vec2 = FixedVec::new(&mut space2);
1037 vec2.push_all(&[1, 2, 3, 4, 5]).unwrap();
1038
1039 assert_eq!(vec1, vec2);
1040 }
1041}