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}