// Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! A vector type intended to be used for collecting from iterators onto the stack. //! //! Space for up to N elements is provided on the stack. If more elements are collected, Vec is //! used to store the values on the heap. //! //! The N above is determined by Array's implementor, by way of an associatated constant. use std::ops::{Deref, DerefMut}; use std::iter::{self, IntoIterator, FromIterator}; use std::slice; use std::vec; use std::collections::range::RangeArgument; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use array_vec::{self, Array, ArrayVec}; #[derive(PartialEq, Eq, Hash, Debug)] pub enum AccumulateVec { Array(ArrayVec), Heap(Vec) } impl Clone for AccumulateVec where A: Array, A::Element: Clone { fn clone(&self) -> Self { match *self { AccumulateVec::Array(ref arr) => AccumulateVec::Array(arr.clone()), AccumulateVec::Heap(ref vec) => AccumulateVec::Heap(vec.clone()), } } } impl AccumulateVec { pub fn new() -> AccumulateVec { AccumulateVec::Array(ArrayVec::new()) } pub fn one(el: A::Element) -> Self { iter::once(el).collect() } pub fn many>(iter: I) -> Self { iter.into_iter().collect() } pub fn len(&self) -> usize { match *self { AccumulateVec::Array(ref arr) => arr.len(), AccumulateVec::Heap(ref vec) => vec.len(), } } pub fn is_empty(&self) -> bool { self.len() == 0 } pub fn pop(&mut self) -> Option { match *self { AccumulateVec::Array(ref mut arr) => arr.pop(), AccumulateVec::Heap(ref mut vec) => vec.pop(), } } pub fn drain(&mut self, range: R) -> Drain where R: RangeArgument { match *self { AccumulateVec::Array(ref mut v) => { Drain::Array(v.drain(range)) }, AccumulateVec::Heap(ref mut v) => { Drain::Heap(v.drain(range)) }, } } } impl Deref for AccumulateVec { type Target = [A::Element]; fn deref(&self) -> &Self::Target { match *self { AccumulateVec::Array(ref v) => &v[..], AccumulateVec::Heap(ref v) => &v[..], } } } impl DerefMut for AccumulateVec { fn deref_mut(&mut self) -> &mut [A::Element] { match *self { AccumulateVec::Array(ref mut v) => &mut v[..], AccumulateVec::Heap(ref mut v) => &mut v[..], } } } impl FromIterator for AccumulateVec { fn from_iter(iter: I) -> AccumulateVec where I: IntoIterator { let iter = iter.into_iter(); if iter.size_hint().1.map_or(false, |n| n <= A::LEN) { let mut v = ArrayVec::new(); v.extend(iter); AccumulateVec::Array(v) } else { AccumulateVec::Heap(iter.collect()) } } } pub struct IntoIter { repr: IntoIterRepr, } enum IntoIterRepr { Array(array_vec::Iter), Heap(vec::IntoIter), } impl Iterator for IntoIter { type Item = A::Element; fn next(&mut self) -> Option { match self.repr { IntoIterRepr::Array(ref mut arr) => arr.next(), IntoIterRepr::Heap(ref mut iter) => iter.next(), } } fn size_hint(&self) -> (usize, Option) { match self.repr { IntoIterRepr::Array(ref iter) => iter.size_hint(), IntoIterRepr::Heap(ref iter) => iter.size_hint(), } } } pub enum Drain<'a, A: Array> where A::Element: 'a { Array(array_vec::Drain<'a, A>), Heap(vec::Drain<'a, A::Element>), } impl<'a, A: Array> Iterator for Drain<'a, A> { type Item = A::Element; fn next(&mut self) -> Option { match *self { Drain::Array(ref mut drain) => drain.next(), Drain::Heap(ref mut drain) => drain.next(), } } fn size_hint(&self) -> (usize, Option) { match *self { Drain::Array(ref drain) => drain.size_hint(), Drain::Heap(ref drain) => drain.size_hint(), } } } impl IntoIterator for AccumulateVec { type Item = A::Element; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter { repr: match self { AccumulateVec::Array(arr) => IntoIterRepr::Array(arr.into_iter()), AccumulateVec::Heap(vec) => IntoIterRepr::Heap(vec.into_iter()), } } } } impl<'a, A: Array> IntoIterator for &'a AccumulateVec { type Item = &'a A::Element; type IntoIter = slice::Iter<'a, A::Element>; fn into_iter(self) -> Self::IntoIter { self.iter() } } impl<'a, A: Array> IntoIterator for &'a mut AccumulateVec { type Item = &'a mut A::Element; type IntoIter = slice::IterMut<'a, A::Element>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } impl From> for AccumulateVec { fn from(v: Vec) -> AccumulateVec { AccumulateVec::many(v) } } impl Default for AccumulateVec { fn default() -> AccumulateVec { AccumulateVec::new() } } impl Encodable for AccumulateVec where A: Array, A::Element: Encodable { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { try!(s.emit_seq_elt(i, |s| e.encode(s))); } Ok(()) }) } } impl Decodable for AccumulateVec where A: Array, A::Element: Decodable { fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { Ok(try!((0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect())) }) } }