Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/tt/src/lib.rs')
| -rw-r--r-- | crates/tt/src/lib.rs | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index 83681c5339..b87c7ff475 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs @@ -23,10 +23,10 @@ pub enum TokenTree<S> { } impl_from!(Leaf<S>, Subtree<S> for TokenTree); impl<S: Span> TokenTree<S> { - pub const fn empty(span: S) -> Self { + pub fn empty(span: S) -> Self { Self::Subtree(Subtree { delimiter: Delimiter::invisible_spanned(span), - token_trees: vec![], + token_trees: Box::new([]), }) } @@ -34,7 +34,7 @@ impl<S: Span> TokenTree<S> { match self { TokenTree::Leaf(_) => Subtree { delimiter: Delimiter::invisible_delim_spanned(span), - token_trees: vec![self], + token_trees: Box::new([self]), }, TokenTree::Subtree(s) => s, } @@ -69,12 +69,35 @@ impl_from!(Literal<S>, Punct<S>, Ident<S> for Leaf); #[derive(Clone, PartialEq, Eq, Hash)] pub struct Subtree<S> { pub delimiter: Delimiter<S>, - pub token_trees: Vec<TokenTree<S>>, + pub token_trees: Box<[TokenTree<S>]>, } impl<S: Span> Subtree<S> { - pub const fn empty(span: DelimSpan<S>) -> Self { - Subtree { delimiter: Delimiter::invisible_delim_spanned(span), token_trees: vec![] } + pub fn empty(span: DelimSpan<S>) -> Self { + Subtree { delimiter: Delimiter::invisible_delim_spanned(span), token_trees: Box::new([]) } + } + + /// This is slow, and should be avoided, as it will always reallocate! + pub fn push(&mut self, subtree: TokenTree<S>) { + let mut mutable_trees = std::mem::take(&mut self.token_trees).into_vec(); + + // Reserve exactly space for one element, to avoid `into_boxed_slice` having to reallocate again. + mutable_trees.reserve_exact(1); + mutable_trees.push(subtree); + + self.token_trees = mutable_trees.into_boxed_slice(); + } +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct SubtreeBuilder<S> { + pub delimiter: Delimiter<S>, + pub token_trees: Vec<TokenTree<S>>, +} + +impl<S> SubtreeBuilder<S> { + pub fn build(self) -> Subtree<S> { + Subtree { delimiter: self.delimiter, token_trees: self.token_trees.into_boxed_slice() } } } @@ -228,7 +251,7 @@ impl<S> fmt::Display for Subtree<S> { }; f.write_str(l)?; let mut needs_space = false; - for tt in &self.token_trees { + for tt in self.token_trees.iter() { if needs_space { f.write_str(" ")?; } @@ -303,7 +326,7 @@ impl<S> Subtree<S> { let mut res = String::new(); res.push_str(delim.0); let mut last = None; - for child in &self.token_trees { + for child in self.token_trees.iter() { let s = match child { TokenTree::Leaf(it) => { let s = match it { |