Skip to content

Commit cc9dc38

Browse files
committed
Make the generated vector-like object use a single length
Most methods are not implemented
1 parent ccd6af3 commit cc9dc38

File tree

8 files changed

+448
-576
lines changed

8 files changed

+448
-576
lines changed

soa-derive-internal/src/input.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ impl Input {
8181
Ident::new(&format!("{}Vec", self.name), Span::call_site())
8282
}
8383

84+
pub fn vec_fields_name(&self) -> Ident {
85+
Ident::new(&format!("{}VecFields", self.name), Span::call_site())
86+
}
87+
8488
pub fn slice_name(&self) -> Ident {
8589
Ident::new(&format!("{}Slice", self.name), Span::call_site())
8690
}

soa-derive-internal/src/iter.rs

Lines changed: 87 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -15,243 +15,138 @@ pub fn derive(input: &Input) -> TokenStream {
1515
let ref_name = &input.ref_name();
1616
let ref_mut_name = &input.ref_mut_name();
1717

18-
let ref_doc_url = format!("[`{0}`](struct.{0}.html)", ref_name);
19-
let ref_mut_doc_url = format!("[`{0}`](struct.{0}.html)", ref_mut_name);
2018

21-
let fields_names = &input.fields.iter()
22-
.map(|field| field.ident.clone().unwrap())
23-
.collect::<Vec<_>>();
24-
let first_field = &fields_names[0];
19+
let fields_names = input.fields.iter()
20+
.map(|field| field.ident.clone().unwrap())
21+
.collect::<Vec<_>>();
22+
let fields_names_1 = &fields_names;
23+
let fields_names_2 = &fields_names;
2524

26-
let fields_types = &input.fields.iter()
27-
.map(|field| &field.ty)
28-
.collect::<Vec<_>>();
29-
let first_field_type = &fields_types[0];
30-
31-
let mut iter_type = quote!{
32-
slice::Iter<'a, #first_field_type>
33-
};
34-
let mut iter_pat = quote!{
35-
#first_field
36-
};
37-
let mut create_iter = quote!{
38-
self.#first_field.iter()
39-
};
40-
41-
let mut iter_mut_type = quote!{
42-
slice::IterMut<'a, #first_field_type>
43-
};
44-
let mut create_iter_mut = quote!{
45-
self.#first_field.iter_mut()
46-
};
47-
48-
if fields_types.len() > 1 {
49-
for field in &input.fields[1..] {
50-
let field_name = &field.ident;
51-
let field_type = &field.ty;
52-
53-
iter_pat = quote!{
54-
(#iter_pat, #field_name)
55-
};
56-
57-
iter_type = quote!{
58-
iter::Zip<#iter_type, slice::Iter<'a, #field_type>>
59-
};
60-
61-
create_iter = quote!{
62-
#create_iter.zip(self.#field_name.iter())
63-
};
64-
65-
iter_mut_type = quote!{
66-
iter::Zip<#iter_mut_type, slice::IterMut<'a, #field_type>>
67-
};
68-
69-
create_iter_mut = quote!{
70-
#create_iter_mut.zip(self.#field_name.iter_mut())
71-
};
72-
}
73-
}
74-
75-
let mut generated = quote! {
25+
let generated = quote!{
7626
#[allow(non_snake_case, dead_code)]
7727
mod #detail_mod {
7828
use super::*;
79-
use std::slice;
80-
#[allow(unused_imports)]
81-
use std::iter;
8229

83-
#[allow(missing_debug_implementations)]
84-
#visibility struct Iter<'a>(pub(super) #iter_type);
85-
86-
impl<'a> Iterator for Iter<'a> {
87-
type Item = #ref_name<'a>;
88-
89-
#[inline]
90-
fn next(&mut self) -> Option<#ref_name<'a>> {
91-
self.0.next().and_then(|#iter_pat|
92-
Some(#ref_name{
93-
#(#fields_names,)*
94-
})
95-
)
96-
}
97-
98-
#[inline]
99-
fn size_hint(&self) -> (usize, Option<usize>) {
100-
self.0.size_hint()
101-
}
102-
}
103-
104-
impl<'a> DoubleEndedIterator for Iter<'a> {
105-
106-
#[inline]
107-
fn next_back(&mut self) -> Option<#ref_name<'a>> {
108-
self.0.next_back().and_then(|#iter_pat|
109-
Some(#ref_name{
110-
#(#fields_names,)*
111-
})
112-
)
113-
}
114-
}
115-
116-
impl #vec_name {
117-
/// Get an iterator over the
118-
#[doc = #ref_doc_url]
119-
/// in this vector
120-
#visibility fn iter(&self) -> Iter {
121-
Iter(#create_iter)
122-
}
30+
pub struct VecIter<'a> {
31+
pub(super) vec: &'a #vec_name,
32+
pub(super) n: usize,
12333
}
12434

125-
impl<'a> #slice_name<'a> {
126-
/// Get an iterator over the
127-
#[doc = #ref_doc_url]
128-
/// in this slice.
129-
#visibility fn iter(&self) -> Iter {
130-
Iter(#create_iter)
35+
impl<'a> VecIter<'a> {
36+
pub(self) fn new(vec: &'a #vec_name) -> VecIter<'a> {
37+
VecIter {
38+
vec,
39+
n: 0,
40+
}
13141
}
13242
}
13343

134-
#[allow(missing_debug_implementations)]
135-
#visibility struct IterMut<'a>(pub(super) #iter_mut_type);
44+
impl<'a> Iterator for VecIter<'a> {
45+
type Item = #ref_name<'a>;
13646

137-
impl<'a> Iterator for IterMut<'a> {
138-
type Item = #ref_mut_name<'a>;
47+
fn next(&mut self) -> Option<Self::Item> {
48+
if self.n >= self.vec.len() {
49+
return None;
50+
}
13951

140-
#[inline]
141-
fn next(&mut self) -> Option<#ref_mut_name<'a>> {
142-
self.0.next().and_then(|#iter_pat|
143-
Some(#ref_mut_name{
144-
#(#fields_names,)*
52+
let item = unsafe {
53+
Some(#ref_name {
54+
#(
55+
#fields_names_1: self.vec.data.#fields_names_2.ptr().add(self.n).as_ref().unwrap(),
56+
)*
14557
})
146-
)
58+
};
59+
self.n += 1;
60+
item
14761
}
14862

149-
#[inline]
15063
fn size_hint(&self) -> (usize, Option<usize>) {
151-
self.0.size_hint()
64+
if self.n >= self.vec.len() {
65+
return (0, Some(0))
66+
}
67+
let left = self.vec.len() - self.n;
68+
(left, Some(left))
15269
}
15370
}
15471

155-
impl<'a> DoubleEndedIterator for IterMut<'a> {
156-
157-
#[inline]
158-
fn next_back(&mut self) -> Option<#ref_mut_name<'a>> {
159-
self.0.next_back().and_then(|#iter_pat|
160-
Some(#ref_mut_name{
161-
#(#fields_names,)*
162-
})
163-
)
164-
}
72+
pub struct VecIterMut<'a> {
73+
pub(super) vec: &'a mut #vec_name,
74+
pub(super) n: usize,
16575
}
16676

167-
impl #vec_name {
168-
/// Get a mutable iterator over the
169-
#[doc = #ref_mut_doc_url]
170-
/// in this vector
171-
#visibility fn iter_mut(&mut self) -> IterMut {
172-
IterMut(#create_iter_mut)
77+
impl<'a> VecIterMut<'a> {
78+
pub(self) fn new(vec: &'a mut #vec_name) -> VecIterMut<'a> {
79+
VecIterMut {
80+
vec,
81+
n: 0,
82+
}
17383
}
17484
}
17585

176-
impl<'a> #slice_mut_name<'a> {
177-
/// Get an iterator over the
178-
#[doc = #ref_doc_url]
179-
/// in this vector
180-
#visibility fn iter(&mut self) -> Iter {
181-
Iter(#create_iter)
182-
}
18386

184-
/// Get a mutable iterator over the
185-
#[doc = #ref_mut_doc_url]
186-
/// in this vector
187-
#visibility fn iter_mut(&mut self) -> IterMut {
188-
IterMut(#create_iter_mut)
189-
}
190-
}
191-
}
192-
};
87+
impl<'a> Iterator for VecIterMut<'a> {
88+
type Item = #ref_mut_name<'a>;
19389

194-
if let Visibility::Public(_) = *visibility {
195-
generated.append_all(quote!{
196-
impl<'a> IntoIterator for #slice_name<'a> {
197-
type Item = #ref_name<'a>;
198-
type IntoIter = #detail_mod::Iter<'a>;
90+
fn next(&mut self) -> Option<Self::Item> {
91+
if self.n >= self.vec.len() {
92+
return None;
93+
}
19994

200-
fn into_iter(self) -> Self::IntoIter {
201-
#detail_mod::Iter(#create_iter)
95+
let item = unsafe {
96+
Some(#ref_mut_name {
97+
#(
98+
#fields_names_1: self.vec.data.#fields_names_2.ptr().add(self.n).as_mut().unwrap(),
99+
)*
100+
})
101+
};
102+
self.n += 1;
103+
item
202104
}
203-
}
204-
205105

206-
impl std::iter::FromIterator<#name> for #vec_name {
207-
fn from_iter<T: IntoIterator<Item=#name>>(iter: T) -> Self {
208-
let mut result = #vec_name::new();
209-
for element in iter {
210-
#(
211-
(result.#fields_names).push(element.#fields_names);
212-
)*
106+
fn size_hint(&self) -> (usize, Option<usize>) {
107+
if self.n >= self.vec.len() {
108+
return (0, Some(0))
213109
}
214-
result
110+
let left = self.vec.len() - self.n;
111+
(left, Some(left))
215112
}
216113
}
114+
}
217115

218-
impl<'a, 'b> IntoIterator for &'a #slice_name<'b> {
219-
type Item = #ref_name<'a>;
220-
type IntoIter = #detail_mod::Iter<'a>;
221-
222-
fn into_iter(self) -> Self::IntoIter {
223-
#detail_mod::Iter(#create_iter)
116+
impl #vec_name {
117+
pub fn iter<'a>(&'a self) -> #detail_mod::VecIter<'a> {
118+
#detail_mod::VecIter {
119+
vec: self,
120+
n: 0,
224121
}
225122
}
226123

227-
impl<'a> IntoIterator for &'a #vec_name {
228-
type Item = #ref_name<'a>;
229-
type IntoIter = #detail_mod::Iter<'a>;
230-
231-
fn into_iter(self) -> Self::IntoIter {
232-
#detail_mod::Iter(#create_iter)
124+
pub fn iter_mut<'a>(&'a mut self) -> #detail_mod::VecIterMut<'a> {
125+
#detail_mod::VecIterMut {
126+
vec: self,
127+
n: 0,
233128
}
234129
}
130+
}
235131

236-
impl<'a> IntoIterator for #slice_mut_name<'a> {
237-
type Item = #ref_mut_name<'a>;
238-
type IntoIter = #detail_mod::IterMut<'a>;
132+
impl<'a> IntoIterator for &'a #vec_name {
133+
type Item = #ref_name<'a>;
134+
type IntoIter = #detail_mod::VecIter<'a>;
239135

240-
fn into_iter(self) -> Self::IntoIter {
241-
#detail_mod::IterMut(#create_iter_mut)
242-
}
136+
fn into_iter(self) -> Self::IntoIter {
137+
return self.iter()
243138
}
139+
}
244140

245-
impl<'a> IntoIterator for &'a mut #vec_name {
246-
type Item = #ref_mut_name<'a>;
247-
type IntoIter = #detail_mod::IterMut<'a>;
141+
impl<'a> IntoIterator for &'a mut #vec_name {
142+
type Item = #ref_mut_name<'a>;
143+
type IntoIter = #detail_mod::VecIterMut<'a>;
248144

249-
fn into_iter(self) -> Self::IntoIter {
250-
#detail_mod::IterMut(#create_iter_mut)
251-
}
145+
fn into_iter(self) -> Self::IntoIter {
146+
return self.iter_mut()
252147
}
253-
});
254-
}
148+
}
149+
};
255150

256151
return generated;
257152
}

soa-derive-internal/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn soa_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
2929
generated.append_all(slice::derive_mut(&input));
3030
generated.append_all(iter::derive(&input));
3131
generated.append_all(derive_trait(&input));
32+
// println!("{}", generated); // Useful for debugging.
3233
generated.into()
3334
}
3435

soa-derive-internal/src/ptr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub fn derive(input: &Input) -> TokenStream {
191191
})
192192
}
193193
}
194-
194+
195195
/// Similar to [`*mut T::as_mut()`](https://doc.rust-lang.org/std/primitive.pointer.html#method.as_mut),
196196
/// with the same safety caveats.
197197
pub unsafe fn as_mut<'a>(self) -> Option<#ref_mut_name<'a>> {
@@ -293,7 +293,7 @@ pub fn derive(input: &Input) -> TokenStream {
293293
#(self.#fields_names_1.write_unaligned(val.#fields_names_2); )*
294294
}
295295
}
296-
296+
297297
#[allow(dead_code)]
298298
impl<'a> #ref_name<'a> {
299299
/// Convert a
@@ -307,7 +307,7 @@ pub fn derive(input: &Input) -> TokenStream {
307307
}
308308
}
309309
}
310-
310+
311311
#[allow(dead_code)]
312312
impl<'a> #ref_mut_name<'a> {
313313
/// Convert a
@@ -320,7 +320,7 @@ pub fn derive(input: &Input) -> TokenStream {
320320
#(#fields_names_1: self.#fields_names_2, )*
321321
}
322322
}
323-
323+
324324
/// Convert a
325325
#[doc = #ref_mut_doc_url]
326326
/// to a

0 commit comments

Comments
 (0)