@@ -15,7 +15,6 @@ use middle::ty_fold;
1515use middle:: ty_fold:: { TypeFoldable , TypeFolder } ;
1616use util:: ppaux:: Repr ;
1717
18- use std:: iter:: Chain ;
1918use std:: mem;
2019use std:: raw;
2120use std:: slice:: { Items , MutItems } ;
@@ -191,8 +190,8 @@ impl Substs {
191190 }
192191
193192 pub fn with_method_from ( self , substs : & Substs ) -> Substs {
194- self . with_method ( ( * substs. types . get_vec ( FnSpace ) ) . clone ( ) ,
195- ( * substs. regions ( ) . get_vec ( FnSpace ) ) . clone ( ) )
193+ self . with_method ( Vec :: from_slice ( substs. types . get_slice ( FnSpace ) ) ,
194+ Vec :: from_slice ( substs. regions ( ) . get_slice ( FnSpace ) ) )
196195 }
197196
198197 pub fn with_method ( self ,
@@ -261,13 +260,44 @@ impl ParamSpace {
261260 */
262261#[ deriving( PartialEq , Eq , Clone , Hash , Encodable , Decodable ) ]
263262pub struct VecPerParamSpace < T > {
264- vecs : ( Vec < T > , Vec < T > , Vec < T > )
263+ // This was originally represented as a tuple with one Vec<T> for
264+ // each variant of ParamSpace, and that remains the abstraction
265+ // that it provides to its clients.
266+ //
267+ // Here is how the representation corresponds to the abstraction
268+ // i.e. the "abstraction function" AF:
269+ //
270+ // AF(self) = (self.content.slice_to(self.type_limit),
271+ // self.content.slice(self.type_limit, self.self_limit),
272+ // self.content.slice_from(self.self_limit))
273+ type_limit : uint ,
274+ self_limit : uint ,
275+ content : Vec < T > ,
276+ }
277+
278+ impl < T : Clone > VecPerParamSpace < T > {
279+ pub fn push_all ( & mut self , space : ParamSpace , values : & [ T ] ) {
280+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
281+ for t in values. iter ( ) {
282+ self . push ( space, t. clone ( ) ) ;
283+ }
284+ }
265285}
266286
267287impl < T > VecPerParamSpace < T > {
288+ fn limits ( & self , space : ParamSpace ) -> ( uint , uint ) {
289+ match space {
290+ TypeSpace => ( 0 , self . type_limit ) ,
291+ SelfSpace => ( self . type_limit , self . self_limit ) ,
292+ FnSpace => ( self . self_limit , self . content . len ( ) ) ,
293+ }
294+ }
295+
268296 pub fn empty ( ) -> VecPerParamSpace < T > {
269297 VecPerParamSpace {
270- vecs : ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) )
298+ type_limit : 0 ,
299+ self_limit : 0 ,
300+ content : Vec :: new ( )
271301 }
272302 }
273303
@@ -276,8 +306,15 @@ impl<T> VecPerParamSpace<T> {
276306 }
277307
278308 pub fn new ( t : Vec < T > , s : Vec < T > , f : Vec < T > ) -> VecPerParamSpace < T > {
309+ let type_limit = t. len ( ) ;
310+ let self_limit = t. len ( ) + s. len ( ) ;
311+ let mut content = t;
312+ content. push_all_move ( s) ;
313+ content. push_all_move ( f) ;
279314 VecPerParamSpace {
280- vecs : ( t, s, f)
315+ type_limit : type_limit,
316+ self_limit : self_limit,
317+ content : content,
281318 }
282319 }
283320
@@ -289,55 +326,98 @@ impl<T> VecPerParamSpace<T> {
289326 result
290327 }
291328
329+ /// Appends `value` to the vector associated with `space`.
330+ ///
331+ /// Unlike the `push` method in `Vec`, this should not be assumed
332+ /// to be a cheap operation (even when amortized over many calls).
292333 pub fn push ( & mut self , space : ParamSpace , value : T ) {
293- self . get_mut_vec ( space) . push ( value) ;
334+ let ( _, limit) = self . limits ( space) ;
335+ match space {
336+ TypeSpace => { self . type_limit += 1 ; self . self_limit += 1 ; }
337+ SelfSpace => { self . self_limit += 1 ; }
338+ FnSpace => { }
339+ }
340+ self . content . insert ( limit, value) ;
341+ }
342+
343+ pub fn pop ( & mut self , space : ParamSpace ) -> Option < T > {
344+ let ( start, limit) = self . limits ( space) ;
345+ if start == limit {
346+ None
347+ } else {
348+ match space {
349+ TypeSpace => { self . type_limit -= 1 ; self . self_limit -= 1 ; }
350+ SelfSpace => { self . self_limit -= 1 ; }
351+ FnSpace => { }
352+ }
353+ self . content . remove ( limit - 1 )
354+ }
355+ }
356+
357+ pub fn truncate ( & mut self , space : ParamSpace , len : uint ) {
358+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
359+ while self . len ( space) > len {
360+ self . pop ( space) ;
361+ }
362+ }
363+
364+ pub fn replace ( & mut self , space : ParamSpace , elems : Vec < T > ) {
365+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
366+ self . truncate ( space, 0 ) ;
367+ for t in elems. move_iter ( ) {
368+ self . push ( space, t) ;
369+ }
294370 }
295371
296372 pub fn get_self < ' a > ( & ' a self ) -> Option < & ' a T > {
297- let v = self . get_vec ( SelfSpace ) ;
373+ let v = self . get_slice ( SelfSpace ) ;
298374 assert ! ( v. len( ) <= 1 ) ;
299- if v. len ( ) == 0 { None } else { Some ( v . get ( 0 ) ) }
375+ if v. len ( ) == 0 { None } else { Some ( & v [ 0 ] ) }
300376 }
301377
302378 pub fn len ( & self , space : ParamSpace ) -> uint {
303- self . get_vec ( space) . len ( )
379+ self . get_slice ( space) . len ( )
380+ }
381+
382+ pub fn is_empty_in ( & self , space : ParamSpace ) -> bool {
383+ self . len ( space) == 0
304384 }
305385
306- pub fn get_vec < ' a > ( & ' a self , space : ParamSpace ) -> & ' a Vec < T > {
307- self . vecs . get ( space as uint ) . unwrap ( )
386+ pub fn get_slice < ' a > ( & ' a self , space : ParamSpace ) -> & ' a [ T ] {
387+ let ( start, limit) = self . limits ( space) ;
388+ self . content . slice ( start, limit)
308389 }
309390
310- pub fn get_mut_vec < ' a > ( & ' a mut self , space : ParamSpace ) -> & ' a mut Vec < T > {
311- self . vecs . get_mut ( space as uint ) . unwrap ( )
391+ fn get_mut_slice < ' a > ( & ' a mut self , space : ParamSpace ) -> & ' a mut [ T ] {
392+ let ( start, limit) = self . limits ( space) ;
393+ self . content . mut_slice ( start, limit)
312394 }
313395
314396 pub fn opt_get < ' a > ( & ' a self ,
315397 space : ParamSpace ,
316398 index : uint )
317399 -> Option < & ' a T > {
318- let v = self . get_vec ( space) ;
319- if index < v. len ( ) { Some ( v . get ( index) ) } else { None }
400+ let v = self . get_slice ( space) ;
401+ if index < v. len ( ) { Some ( & v [ index] ) } else { None }
320402 }
321403
322404 pub fn get < ' a > ( & ' a self , space : ParamSpace , index : uint ) -> & ' a T {
323- self . get_vec ( space) . get ( index)
405+ & self . get_slice ( space) [ index]
324406 }
325407
326408 pub fn get_mut < ' a > ( & ' a mut self ,
327409 space : ParamSpace ,
328410 index : uint ) -> & ' a mut T {
329- self . get_mut_vec ( space) . get_mut ( index)
411+ & mut self . get_mut_slice ( space) [ index]
330412 }
331413
332- pub fn iter < ' a > ( & ' a self ) -> Chain < Items < ' a , T > ,
333- Chain < Items < ' a , T > ,
334- Items < ' a , T > > > {
335- let ( ref r, ref s, ref f) = self . vecs ;
336- r. iter ( ) . chain ( s. iter ( ) . chain ( f. iter ( ) ) )
414+ pub fn iter < ' a > ( & ' a self ) -> Items < ' a , T > {
415+ self . content . iter ( )
337416 }
338417
339- pub fn all_vecs ( & self , pred: |& Vec < T > | -> bool ) -> bool {
340- self . vecs . iter ( ) . all ( pred)
418+ pub fn all_vecs ( & self , pred: |& [ T ] | -> bool) -> bool {
419+ let spaces = [ TypeSpace , SelfSpace , FnSpace ] ;
420+ spaces. iter ( ) . all ( |& space| { pred ( self . get_slice ( space) ) } )
341421 }
342422
343423 pub fn all ( & self , pred: |& T | -> bool) -> bool {
@@ -353,9 +433,13 @@ impl<T> VecPerParamSpace<T> {
353433 }
354434
355435 pub fn map < U > ( & self , pred: |& T | -> U ) -> VecPerParamSpace < U > {
356- VecPerParamSpace :: new ( self . vecs . ref0 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
357- self . vecs . ref1 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
358- self . vecs . ref2 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
436+ // FIXME (#15418): this could avoid allocating the intermediate
437+ // Vec's, but note that the values of type_limit and self_limit
438+ // also need to be kept in sync during construction.
439+ VecPerParamSpace :: new (
440+ self . get_slice ( TypeSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
441+ self . get_slice ( SelfSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
442+ self . get_slice ( FnSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
359443 }
360444
361445 pub fn map_rev < U > ( & self , pred: |& T | -> U ) -> VecPerParamSpace < U > {
@@ -368,29 +452,46 @@ impl<T> VecPerParamSpace<T> {
368452 * can be run to a fixed point
369453 */
370454
371- let mut fns: Vec < U > = self . vecs . ref2 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
455+ let mut fns: Vec < U > = self . get_slice ( FnSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
372456
373457 // NB: Calling foo.rev().map().rev() causes the calls to map
374458 // to occur in the wrong order. This was somewhat surprising
375459 // to me, though it makes total sense.
376460 fns. reverse ( ) ;
377461
378- let mut selfs: Vec < U > = self . vecs . ref1 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
462+ let mut selfs: Vec < U > = self . get_slice ( SelfSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
379463 selfs. reverse ( ) ;
380- let mut tys: Vec < U > = self . vecs . ref0 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
464+ let mut tys: Vec < U > = self . get_slice ( TypeSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
381465 tys. reverse ( ) ;
382466 VecPerParamSpace :: new ( tys, selfs, fns)
383467 }
384468
385469 pub fn split ( self ) -> ( Vec < T > , Vec < T > , Vec < T > ) {
386- self . vecs
470+ // FIXME (#15418): this does two traversals when in principle
471+ // one would suffice. i.e. change to use `move_iter`.
472+ let VecPerParamSpace { type_limit, self_limit, content } = self ;
473+ let mut i = 0 ;
474+ let ( prefix, fn_vec) = content. partition ( |_| {
475+ let on_left = i < self_limit;
476+ i += 1 ;
477+ on_left
478+ } ) ;
479+
480+ let mut i = 0 ;
481+ let ( type_vec, self_vec) = prefix. partition ( |_| {
482+ let on_left = i < type_limit;
483+ i += 1 ;
484+ on_left
485+ } ) ;
486+
487+ ( type_vec, self_vec, fn_vec)
387488 }
388489
389490 pub fn with_vec ( mut self , space : ParamSpace , vec : Vec < T > )
390491 -> VecPerParamSpace < T >
391492 {
392- assert ! ( self . get_vec ( space) . is_empty ( ) ) ;
393- * self . get_mut_vec ( space) = vec;
493+ assert ! ( self . is_empty_in ( space) ) ;
494+ self . replace ( space, vec) ;
394495 self
395496 }
396497}
0 commit comments