From 2fa1da991945b2c2d3b36241492f7e8280869fd0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 12 Aug 2018 12:45:48 -0700 Subject: TokenStream::extend --- src/libsyntax/util/rc_vec.rs | 95 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/libsyntax/util/rc_vec.rs (limited to 'src/libsyntax/util') diff --git a/src/libsyntax/util/rc_vec.rs b/src/libsyntax/util/rc_vec.rs new file mode 100644 index 00000000000..b2785d7143d --- /dev/null +++ b/src/libsyntax/util/rc_vec.rs @@ -0,0 +1,95 @@ +// Copyright 2017 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. + +use std::fmt; +use std::ops::{Deref, Range}; + +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use rustc_data_structures::sync::Lrc; + +#[derive(Clone)] +pub struct RcVec { + data: Lrc>, + offset: u32, + len: u32, +} + +impl RcVec { + pub fn new(mut vec: Vec) -> Self { + // By default, constructing RcVec from Vec gives it just enough capacity + // to hold the initial elements. Callers that anticipate needing to + // extend the vector may prefer RcVec::new_preserving_capacity. + vec.shrink_to_fit(); + + RcVec { + offset: 0, + len: vec.len() as u32, + data: Lrc::new(vec), + } + } + + pub fn new_preserving_capacity(vec: Vec) -> Self { + RcVec { + offset: 0, + len: vec.len() as u32, + data: Lrc::new(vec), + } + } + + pub fn sub_slice(&self, range: Range) -> Self { + RcVec { + data: self.data.clone(), + offset: self.offset + range.start as u32, + len: (range.end - range.start) as u32, + } + } + + /// If this RcVec has exactly one strong reference, returns ownership of the + /// underlying vector. Otherwise returns self unmodified. + pub fn try_unwrap(self) -> Result, Self> { + match Lrc::try_unwrap(self.data) { + // If no other RcVec shares ownership of this data. + Ok(mut vec) => { + // Drop any elements after our view of the data. + vec.truncate(self.offset as usize + self.len as usize); + // Drop any elements before our view of the data. + if self.offset != 0 { + vec.drain(..self.offset as usize); + } + Ok(vec) + } + + // If the data is shared. + Err(data) => Err(RcVec { data, ..self }), + } + } +} + +impl Deref for RcVec { + type Target = [T]; + fn deref(&self) -> &[T] { + &self.data[self.offset as usize..(self.offset + self.len) as usize] + } +} + +impl fmt::Debug for RcVec { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.deref(), f) + } +} + +impl HashStable for RcVec +where + T: HashStable, +{ + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); + } +} -- cgit 1.4.1-3-g733a5 From 69b9c23b3858dc87ceb6629b7640d5f579b8ed79 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 13 Aug 2018 17:09:13 -0700 Subject: Address review of RcVec --- src/libsyntax/util/rc_vec.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/libsyntax/util') diff --git a/src/libsyntax/util/rc_vec.rs b/src/libsyntax/util/rc_vec.rs index b2785d7143d..99fbce1ad91 100644 --- a/src/libsyntax/util/rc_vec.rs +++ b/src/libsyntax/util/rc_vec.rs @@ -27,12 +27,7 @@ impl RcVec { // to hold the initial elements. Callers that anticipate needing to // extend the vector may prefer RcVec::new_preserving_capacity. vec.shrink_to_fit(); - - RcVec { - offset: 0, - len: vec.len() as u32, - data: Lrc::new(vec), - } + Self::new_preserving_capacity(vec) } pub fn new_preserving_capacity(vec: Vec) -> Self { @@ -59,10 +54,10 @@ impl RcVec { Ok(mut vec) => { // Drop any elements after our view of the data. vec.truncate(self.offset as usize + self.len as usize); - // Drop any elements before our view of the data. - if self.offset != 0 { - vec.drain(..self.offset as usize); - } + // Drop any elements before our view of the data. Do this after + // the `truncate` so that elements past the end of our view do + // not need to be copied around. + vec.drain(..self.offset as usize); Ok(vec) } -- cgit 1.4.1-3-g733a5