use self::LockstepIterSize::*;
use ast::Ident;
-use syntax_pos::{Span, DUMMY_SP};
use errors::{Handler, DiagnosticBuilder};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use parse::token::{DocComment, MatchNt, SubstNt};
use parse::token::{Token, Interpolated, NtIdent, NtTT};
use parse::token;
use parse::lexer::TokenAndSpan;
+use syntax_pos::{Span, DUMMY_SP};
use tokenstream::{self, TokenTree};
+use util::small_vector::SmallVector;
use std::rc::Rc;
use std::ops::Add;
pub struct TtReader<'a> {
pub sp_diag: &'a Handler,
/// the unzipped tree:
- stack: Vec<TtFrame>,
+ stack: SmallVector<TtFrame>,
/* for MBE-style macro transcription */
interpolations: HashMap<Ident, Rc<NamedMatch>>,
-> TtReader {
let mut r = TtReader {
sp_diag: sp_diag,
- stack: vec!(TtFrame {
+ stack: SmallVector::one(TtFrame {
forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: src,
// doesn't matter. This merely holds the root unzipping.
#![feature(rustc_diagnostic_macros)]
#![feature(specialization)]
+extern crate core;
extern crate serialize;
extern crate term;
extern crate libc;
use self::SmallVectorRepr::*;
use self::IntoIterRepr::*;
+use core::ops;
use std::iter::{IntoIterator, FromIterator};
use std::mem;
use std::slice;
use util::move_map::MoveMap;
/// A vector type optimized for cases where the size is almost always 0 or 1
+#[derive(Clone)]
pub struct SmallVector<T> {
repr: SmallVectorRepr<T>,
}
+#[derive(Clone)]
enum SmallVectorRepr<T> {
Zero,
One(T),
}
pub fn as_slice(&self) -> &[T] {
- match self.repr {
- Zero => {
- let result: &[T] = &[];
- result
- }
- One(ref v) => {
- unsafe { slice::from_raw_parts(v, 1) }
- }
- Many(ref vs) => vs
- }
+ self
+ }
+
+ pub fn as_mut_slice(&mut self) -> &mut [T] {
+ self
}
pub fn pop(&mut self) -> Option<T> {
}
}
+impl<T> ops::Deref for SmallVector<T> {
+ type Target = [T];
+
+ fn deref(&self) -> &[T] {
+ match self.repr {
+ Zero => {
+ let result: &[T] = &[];
+ result
+ }
+ One(ref v) => {
+ unsafe { slice::from_raw_parts(v, 1) }
+ }
+ Many(ref vs) => vs
+ }
+ }
+}
+
+impl<T> ops::DerefMut for SmallVector<T> {
+ fn deref_mut(&mut self) -> &mut [T] {
+ match self.repr {
+ Zero => {
+ let result: &mut [T] = &mut [];
+ result
+ }
+ One(ref mut v) => {
+ unsafe { slice::from_raw_parts_mut(v, 1) }
+ }
+ Many(ref mut vs) => vs
+ }
+ }
+}
+
impl<T> IntoIterator for SmallVector<T> {
type Item = T;
type IntoIter = IntoIter<T>;