]> git.proxmox.com Git - rustc.git/blame - src/librustc_data_structures/accumulate_vec.rs
New upstream version 1.15.0+dfsg1
[rustc.git] / src / librustc_data_structures / accumulate_vec.rs
CommitLineData
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
18use std::ops::{Deref, DerefMut};
19use std::iter::{self, IntoIterator, FromIterator};
20use std::slice;
21use std::vec;
c30ab7b3 22
476ff2be 23use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
c30ab7b3 24
476ff2be
SL
25use array_vec::{self, Array, ArrayVec};
26
27#[derive(PartialEq, Eq, Hash, Debug)]
c30ab7b3
SL
28pub enum AccumulateVec<A: Array> {
29 Array(ArrayVec<A>),
30 Heap(Vec<A::Element>)
31}
32
476ff2be
SL
33impl<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
44impl<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
76impl<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
86impl<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
95impl<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
108pub struct IntoIter<A: Array> {
109 repr: IntoIterRepr<A>,
110}
111
112enum IntoIterRepr<A: Array> {
113 Array(array_vec::Iter<A>),
114 Heap(vec::IntoIter<A::Element>),
115}
116
117impl<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
135impl<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
148impl<'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
156impl<'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
164impl<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
170impl<A: Array> Default for AccumulateVec<A> {
171 fn default() -> AccumulateVec<A> {
172 AccumulateVec::new()
173 }
174}
175
176impl<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
189impl<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