-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add access methods to the generated SoA vectors #28
Changes from 11 commits
e8330e6
1ce49e4
176fe9e
f606253
4701828
3c2fc15
27a5a2a
878499f
f1ebf7e
c65e32a
1697674
93f715e
43c8c8b
c3c3f01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -153,22 +153,47 @@ pub fn derive(input: &Input) -> TokenStream { | |||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get). | ||||||
pub fn get(&self, i: usize) -> Option<#ref_name> { | ||||||
if self.is_empty() || i >= self.len() { | ||||||
None | ||||||
} else { | ||||||
Some(#ref_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get(i).unwrap(),)* | ||||||
}) | ||||||
} | ||||||
pub fn get<'b, I>(&'b self, index: I) -> Option<I::RefOutput> | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.reborrow(); | ||||||
index.get(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get_unchecked()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked). | ||||||
pub unsafe fn get_unchecked(&self, i: usize) -> #ref_name { | ||||||
#ref_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get_unchecked(i),)* | ||||||
pub unsafe fn get_unchecked<'b, I>(&'b self, index: I) -> I::RefOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.reborrow(); | ||||||
index.get_unchecked(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [`std::ops::Index` trait](https://doc.rust-lang.org/std/ops/trait.Index.html) on | ||||||
#[doc = #slice_name_str] | ||||||
/// . | ||||||
/// This is required because we cannot implement that trait. | ||||||
pub fn index<'b, I>(&'b self, index: I) -> I::RefOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.reborrow(); | ||||||
index.index(slice) | ||||||
} | ||||||
|
||||||
/// Reborrows the slices in a more narrower lifetime | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this context There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good! |
||||||
pub fn reborrow<'b>(&'b self) -> #slice_name<'b> | ||||||
where | ||||||
'a: 'b | ||||||
{ | ||||||
#slice_name { | ||||||
#(#fields_names_1: &self.#fields_names_2,)* | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -215,7 +240,6 @@ pub fn derive_mut(input: &Input) -> TokenStream { | |||||
let slice_name = &input.slice_name(); | ||||||
let slice_mut_name = &input.slice_mut_name(); | ||||||
let vec_name = &input.vec_name(); | ||||||
let ref_name = &input.ref_name(); | ||||||
let ref_mut_name = &input.ref_mut_name(); | ||||||
let ptr_name = &input.ptr_name(); | ||||||
let ptr_mut_name = &input.ptr_mut_name(); | ||||||
|
@@ -382,44 +406,95 @@ pub fn derive_mut(input: &Input) -> TokenStream { | |||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get). | ||||||
pub fn get(&self, i: usize) -> Option<#ref_name> { | ||||||
if self.is_empty() || i >= self.len() { | ||||||
None | ||||||
} else { | ||||||
Some(#ref_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get(i).unwrap(),)* | ||||||
}) | ||||||
} | ||||||
pub fn get<'b, I>(&'b self, index: I) -> Option<I::RefOutput> | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.as_slice(); | ||||||
index.get(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get_unchecked()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked). | ||||||
pub unsafe fn get_unchecked(&self, i: usize) -> #ref_name { | ||||||
#ref_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get_unchecked(i),)* | ||||||
} | ||||||
pub unsafe fn get_unchecked<'b, I>(&'b self, index: I) -> I::RefOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.as_slice(); | ||||||
index.get_unchecked(slice) | ||||||
} | ||||||
|
||||||
|
||||||
/// Similar to [`std::ops::Index` trait](https://doc.rust-lang.org/std/ops/trait.Index.html) on | ||||||
#[doc = #slice_name_str] | ||||||
/// . | ||||||
/// This is required because we cannot implement that trait. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
pub fn index<'b, I>(&'b self, index: I) -> I::RefOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndex<#slice_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_name<'b> = self.as_slice(); | ||||||
index.index(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get_mut()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_mut). | ||||||
pub fn get_mut(&mut self, i: usize) -> Option<#ref_mut_name> { | ||||||
if self.is_empty() || i >= self.len() { | ||||||
None | ||||||
} else { | ||||||
Some(#ref_mut_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get_mut(i).unwrap(),)* | ||||||
}) | ||||||
} | ||||||
pub fn get_mut<'b, I>(&'b mut self, index: I) -> Option<I::MutOutput> | ||||||
where | ||||||
I: ::soa_derive::SoAIndexMut<#slice_mut_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_mut_name<'b> = self.reborrow(); | ||||||
index.get_mut(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [` | ||||||
#[doc = #slice_name_str] | ||||||
/// ::get_unchecked_mut()`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked_mut). | ||||||
pub unsafe fn get_unchecked_mut(&mut self, i: usize) -> #ref_mut_name { | ||||||
#ref_mut_name { | ||||||
#(#fields_names_1: self.#fields_names_2.get_unchecked_mut(i),)* | ||||||
pub unsafe fn get_unchecked_mut<'b, I>(&'b mut self, index: I) -> I::MutOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndexMut<#slice_mut_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_mut_name<'b> = self.reborrow(); | ||||||
index.get_unchecked_mut(slice) | ||||||
} | ||||||
|
||||||
/// Similar to [`std::ops::IndexMut` trait](https://doc.rust-lang.org/std/ops/trait.IndexMut.html) on | ||||||
#[doc = #slice_name_str] | ||||||
/// . | ||||||
/// This is required because we cannot implement that trait. | ||||||
pub fn index_mut<'b, I>(&'b mut self, index: I) -> I::MutOutput | ||||||
where | ||||||
I: ::soa_derive::SoAIndexMut<#slice_mut_name<'b>>, | ||||||
'a: 'b | ||||||
{ | ||||||
let slice: #slice_mut_name<'b> = self.reborrow(); | ||||||
index.index_mut(slice) | ||||||
} | ||||||
|
||||||
/// Returns a non-mutable slice from this mutable slice. | ||||||
pub fn as_slice<'b>(&'b self) -> #slice_name<'b> | ||||||
where | ||||||
'a: 'b | ||||||
{ | ||||||
#slice_name { | ||||||
#(#fields_names_1: &self.#fields_names_2,)* | ||||||
} | ||||||
} | ||||||
|
||||||
/// Reborrows the slices in a more narrower lifetime | ||||||
pub fn reborrow<'b>(&'b mut self) -> #slice_mut_name<'b> | ||||||
where | ||||||
'a: 'b | ||||||
{ | ||||||
#slice_mut_name { | ||||||
#(#fields_names_1: &mut *self.#fields_names_2,)* | ||||||
} | ||||||
} | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -168,6 +168,53 @@ pub trait StructOfArray { | |||||
type Type; | ||||||
} | ||||||
|
||||||
|
||||||
mod private_soa_indexs { | ||||||
// From [`std::slice::SliceIndex`](https://doc.rust-lang.org/std/slice/trait.SliceIndex.html) code. | ||||||
// Limits the types that may implement the SoA index traits. | ||||||
// It's also helpful to have the exaustive list of all accepted types. | ||||||
|
||||||
use ::std::ops; | ||||||
|
||||||
pub trait Sealed {} | ||||||
|
||||||
impl Sealed for usize {} // [a] | ||||||
impl Sealed for ops::Range<usize> {} // [a..b] | ||||||
impl Sealed for ops::RangeTo<usize> {} // [..b] | ||||||
impl Sealed for ops::RangeFrom<usize> {} // [a..] | ||||||
impl Sealed for ops::RangeFull {} // [..] | ||||||
impl Sealed for ops::RangeInclusive<usize> {} // [a..=b] | ||||||
impl Sealed for ops::RangeToInclusive<usize> {} // [..=b] | ||||||
} | ||||||
|
||||||
/// Helper trait used for indexing operations. | ||||||
/// Inspired by [`std::slice::SliceIndex`](https://doc.rust-lang.org/std/slice/trait.SliceIndex.html). | ||||||
pub trait SoAIndex<T>: private_soa_indexs::Sealed { | ||||||
/// The output for the non-mutable functions | ||||||
type RefOutput; | ||||||
|
||||||
/// Returns the reference output in this location if in bounds. None otherwise. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
fn get(self, soa: T) -> Option<Self::RefOutput>; | ||||||
/// Returns the reference output in this location withotu performing any bounds check. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
unsafe fn get_unchecked(self, soa: T) -> Self::RefOutput; | ||||||
/// Returns the reference output in this location. Panics if it is not in bounds. | ||||||
fn index(self, soa: T) -> Self::RefOutput; | ||||||
} | ||||||
|
||||||
/// Helper trait used for indexing operations returning mutable. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// Inspired by [`std::slice::SliceIndex`](https://doc.rust-lang.org/std/slice/trait.SliceIndex.html). | ||||||
pub trait SoAIndexMut<T>: private_soa_indexs::Sealed { | ||||||
/// The output for the mutable functions | ||||||
type MutOutput; | ||||||
|
||||||
/// Returns the mutable reference output in this location if in bounds. None otherwise. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
fn get_mut(self, soa: T) -> Option<Self::MutOutput>; | ||||||
/// Returns the mutable reference output in this location withotu performing any bounds check. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
unsafe fn get_unchecked_mut(self, soa: T) -> Self::MutOutput; | ||||||
/// Returns the mutable reference output in this location. Panics if it is not in bounds. | ||||||
fn index_mut(self, soa: T) -> Self::MutOutput; | ||||||
} | ||||||
|
||||||
/// Create an iterator over multiple fields in a Struct of array style vector. | ||||||
/// | ||||||
/// This macro takes two main arguments: the array/slice container, and a list | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.