]>
Commit | Line | Data |
---|---|---|
c30ab7b3 SL |
1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! A vector type intended to be used for collecting from iterators onto the stack. | |
12 | //! | |
13 | //! Space for up to N elements is provided on the stack. If more elements are collected, Vec is | |
476ff2be | 14 | //! used to store the values on the heap. |
c30ab7b3 SL |
15 | //! |
16 | //! The N above is determined by Array's implementor, by way of an associatated constant. | |
17 | ||
476ff2be SL |
18 | use std::ops::{Deref, DerefMut}; |
19 | use std::iter::{self, IntoIterator, FromIterator}; | |
20 | use std::slice; | |
21 | use std::vec; | |
c30ab7b3 | 22 | |
476ff2be | 23 | use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; |
c30ab7b3 | 24 | |
476ff2be SL |
25 | use array_vec::{self, Array, ArrayVec}; |
26 | ||
27 | #[derive(PartialEq, Eq, Hash, Debug)] | |
c30ab7b3 SL |
28 | pub enum AccumulateVec<A: Array> { |
29 | Array(ArrayVec<A>), | |
30 | Heap(Vec<A::Element>) | |
31 | } | |
32 | ||
476ff2be SL |
33 | impl<A> Clone for AccumulateVec<A> |
34 | where A: Array, | |
35 | A::Element: Clone { | |
36 | fn clone(&self) -> Self { | |
37 | match *self { | |
38 | AccumulateVec::Array(ref arr) => AccumulateVec::Array(arr.clone()), | |
39 | AccumulateVec::Heap(ref vec) => AccumulateVec::Heap(vec.clone()), | |
40 | } | |
41 | } | |
42 | } | |
43 | ||
44 | impl<A: Array> AccumulateVec<A> { | |
45 | pub fn new() -> AccumulateVec<A> { | |
46 | AccumulateVec::Array(ArrayVec::new()) | |
47 | } | |
48 | ||
49 | pub fn one(el: A::Element) -> Self { | |
50 | iter::once(el).collect() | |
51 | } | |
52 | ||
53 | pub fn many<I: IntoIterator<Item=A::Element>>(iter: I) -> Self { | |
54 | iter.into_iter().collect() | |
55 | } | |
56 | ||
57 | pub fn len(&self) -> usize { | |
58 | match *self { | |
59 | AccumulateVec::Array(ref arr) => arr.len(), | |
60 | AccumulateVec::Heap(ref vec) => vec.len(), | |
61 | } | |
62 | } | |
63 | ||
64 | pub fn is_empty(&self) -> bool { | |
65 | self.len() == 0 | |
66 | } | |
67 | ||
68 | pub fn pop(&mut self) -> Option<A::Element> { | |
69 | match *self { | |
70 | AccumulateVec::Array(ref mut arr) => arr.pop(), | |
71 | AccumulateVec::Heap(ref mut vec) => vec.pop(), | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
c30ab7b3 SL |
76 | impl<A: Array> Deref for AccumulateVec<A> { |
77 | type Target = [A::Element]; | |
78 | fn deref(&self) -> &Self::Target { | |
79 | match *self { | |
80 | AccumulateVec::Array(ref v) => &v[..], | |
81 | AccumulateVec::Heap(ref v) => &v[..], | |
82 | } | |
83 | } | |
84 | } | |
85 | ||
476ff2be SL |
86 | impl<A: Array> DerefMut for AccumulateVec<A> { |
87 | fn deref_mut(&mut self) -> &mut [A::Element] { | |
88 | match *self { | |
89 | AccumulateVec::Array(ref mut v) => &mut v[..], | |
90 | AccumulateVec::Heap(ref mut v) => &mut v[..], | |
91 | } | |
92 | } | |
93 | } | |
94 | ||
c30ab7b3 SL |
95 | impl<A: Array> FromIterator<A::Element> for AccumulateVec<A> { |
96 | fn from_iter<I>(iter: I) -> AccumulateVec<A> where I: IntoIterator<Item=A::Element> { | |
97 | let iter = iter.into_iter(); | |
98 | if iter.size_hint().1.map_or(false, |n| n <= A::LEN) { | |
99 | let mut v = ArrayVec::new(); | |
100 | v.extend(iter); | |
101 | AccumulateVec::Array(v) | |
102 | } else { | |
103 | AccumulateVec::Heap(iter.collect()) | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
476ff2be SL |
108 | pub struct IntoIter<A: Array> { |
109 | repr: IntoIterRepr<A>, | |
110 | } | |
111 | ||
112 | enum IntoIterRepr<A: Array> { | |
113 | Array(array_vec::Iter<A>), | |
114 | Heap(vec::IntoIter<A::Element>), | |
115 | } | |
116 | ||
117 | impl<A: Array> Iterator for IntoIter<A> { | |
118 | type Item = A::Element; | |
119 | ||
120 | fn next(&mut self) -> Option<A::Element> { | |
121 | match self.repr { | |
122 | IntoIterRepr::Array(ref mut arr) => arr.next(), | |
123 | IntoIterRepr::Heap(ref mut iter) => iter.next(), | |
124 | } | |
125 | } | |
126 | ||
127 | fn size_hint(&self) -> (usize, Option<usize>) { | |
128 | match self.repr { | |
129 | IntoIterRepr::Array(ref iter) => iter.size_hint(), | |
130 | IntoIterRepr::Heap(ref iter) => iter.size_hint(), | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | impl<A: Array> IntoIterator for AccumulateVec<A> { | |
136 | type Item = A::Element; | |
137 | type IntoIter = IntoIter<A>; | |
138 | fn into_iter(self) -> Self::IntoIter { | |
139 | IntoIter { | |
140 | repr: match self { | |
141 | AccumulateVec::Array(arr) => IntoIterRepr::Array(arr.into_iter()), | |
142 | AccumulateVec::Heap(vec) => IntoIterRepr::Heap(vec.into_iter()), | |
143 | } | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | impl<'a, A: Array> IntoIterator for &'a AccumulateVec<A> { | |
149 | type Item = &'a A::Element; | |
150 | type IntoIter = slice::Iter<'a, A::Element>; | |
151 | fn into_iter(self) -> Self::IntoIter { | |
152 | self.iter() | |
153 | } | |
154 | } | |
155 | ||
156 | impl<'a, A: Array> IntoIterator for &'a mut AccumulateVec<A> { | |
157 | type Item = &'a mut A::Element; | |
158 | type IntoIter = slice::IterMut<'a, A::Element>; | |
159 | fn into_iter(self) -> Self::IntoIter { | |
160 | self.iter_mut() | |
161 | } | |
162 | } | |
163 | ||
164 | impl<A: Array> From<Vec<A::Element>> for AccumulateVec<A> { | |
165 | fn from(v: Vec<A::Element>) -> AccumulateVec<A> { | |
166 | AccumulateVec::many(v) | |
167 | } | |
168 | } | |
169 | ||
170 | impl<A: Array> Default for AccumulateVec<A> { | |
171 | fn default() -> AccumulateVec<A> { | |
172 | AccumulateVec::new() | |
173 | } | |
174 | } | |
175 | ||
176 | impl<A> Encodable for AccumulateVec<A> | |
177 | where A: Array, | |
178 | A::Element: Encodable { | |
179 | fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
180 | s.emit_seq(self.len(), |s| { | |
181 | for (i, e) in self.iter().enumerate() { | |
182 | try!(s.emit_seq_elt(i, |s| e.encode(s))); | |
183 | } | |
184 | Ok(()) | |
185 | }) | |
186 | } | |
187 | } | |
188 | ||
189 | impl<A> Decodable for AccumulateVec<A> | |
190 | where A: Array, | |
191 | A::Element: Decodable { | |
192 | fn decode<D: Decoder>(d: &mut D) -> Result<AccumulateVec<A>, D::Error> { | |
193 | d.read_seq(|d, len| { | |
194 | Ok(try!((0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect())) | |
195 | }) | |
196 | } | |
197 | } | |
198 |