]>
git.proxmox.com Git - rustc.git/blob - src/libsyntax/util/map_in_place.rs
1 // FIXME(Centril): Move to rustc_data_structures.
3 use smallvec
::{Array, SmallVec}
;
6 pub trait MapInPlace
<T
>: Sized
{
7 fn map_in_place
<F
>(&mut self, mut f
: F
)
11 self.flat_map_in_place(|e
| Some(f(e
)))
14 fn flat_map_in_place
<F
, I
>(&mut self, f
: F
)
17 I
: IntoIterator
<Item
= T
>;
20 impl<T
> MapInPlace
<T
> for Vec
<T
> {
21 fn flat_map_in_place
<F
, I
>(&mut self, mut f
: F
)
24 I
: IntoIterator
<Item
= T
>,
29 let mut old_len
= self.len();
30 self.set_len(0); // make sure we just leak elements in case of panic
32 while read_i
< old_len
{
33 // move the read_i'th item out of the vector and map it
35 let e
= ptr
::read(self.get_unchecked(read_i
));
36 let iter
= f(e
).into_iter();
41 ptr
::write(self.get_unchecked_mut(write_i
), e
);
44 // If this is reached we ran out of space
45 // in the middle of the vector.
46 // However, the vector is in a valid state here,
47 // so we just do a somewhat inefficient insert.
48 self.set_len(old_len
);
49 self.insert(write_i
, e
);
60 // write_i tracks the number of actually written new items.
61 self.set_len(write_i
);
66 impl<T
, A
: Array
<Item
= T
>> MapInPlace
<T
> for SmallVec
<A
> {
67 fn flat_map_in_place
<F
, I
>(&mut self, mut f
: F
)
70 I
: IntoIterator
<Item
= T
>,
75 let mut old_len
= self.len();
76 self.set_len(0); // make sure we just leak elements in case of panic
78 while read_i
< old_len
{
79 // move the read_i'th item out of the vector and map it
81 let e
= ptr
::read(self.get_unchecked(read_i
));
82 let iter
= f(e
).into_iter();
87 ptr
::write(self.get_unchecked_mut(write_i
), e
);
90 // If this is reached we ran out of space
91 // in the middle of the vector.
92 // However, the vector is in a valid state here,
93 // so we just do a somewhat inefficient insert.
94 self.set_len(old_len
);
95 self.insert(write_i
, e
);
106 // write_i tracks the number of actually written new items.
107 self.set_len(write_i
);