use proc_macro2::TokenStream;
use quote::quote;
use crate::{input::Input, names};
fn resolve_range() -> TokenStream {
quote! {
let start = match index.start_bound() {
core::ops::Bound::Included(i) => *i,
core::ops::Bound::Excluded(i) => i.saturating_add(1),
core::ops::Bound::Unbounded => 0,
};
let n = self.len();
let end = match index.end_bound() {
core::ops::Bound::Included(i) => (*i).saturating_add(1),
core::ops::Bound::Excluded(i) => *i,
core::ops::Bound::Unbounded => n,
};
}
}
pub fn derive_slice(input: &Input) -> TokenStream {
let name = &input.name;
let slice_name = names::slice_name(name);
let ref_name = names::ref_name(&input.name);
let ptr_name = names::ptr_name(&input.name);
let iter_name = names::iter_name(name);
let resolve_range = resolve_range();
let generated = quote! {
impl<'a> ::layout::SoASlice<#name> for #slice_name<'a> {
type Ref<'t> = #ref_name<'t> where Self: 't, 'a: 't;
type Slice<'t> = #slice_name<'t> where Self: 't, 'a: 't;
type Iter<'t> = #iter_name<'t> where Self: 't, 'a: 't;
type Ptr = #ptr_name;
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
fn as_slice<'c>(&'c self) -> Self::Slice<'c> {
self.reborrow::<'c>()
}
fn slice<'c, 'b: 'c>(&'c self, index: impl core::ops::RangeBounds<usize>) -> Self::Slice<'c> where Self: 'b {
#resolve_range
self.index(start..end)
}
fn get<'c>(&'c self, index: usize) -> Option<Self::Ref<'c>> {
self.get(index)
}
fn index<'c>(&'c self, index: usize) -> Self::Ref<'c> {
self.index(index)
}
fn iter<'c>(&'c self) -> Self::Iter<'c> {
self.iter()
}
fn as_ptr(&self) -> Self::Ptr {
self.as_ptr()
}
}
};
return generated;
}
pub fn derive_slice_mut(input: &Input) -> TokenStream {
let name = &input.name;
let slice_name = names::slice_name(name);
let slice_mut_name = names::slice_mut_name(&input.name);
let ref_name = names::ref_name(&input.name);
let ref_mut_name = names::ref_mut_name(&input.name);
let ptr_name = names::ptr_name(&input.name);
let ptr_mut_name = names::ptr_mut_name(&input.name);
let iter_name = names::iter_name(name);
let iter_mut_name = names::iter_mut_name(name);
let resolve_range = resolve_range();
let generated = quote! {
impl<'a> ::layout::SoASliceMut<#name> for #slice_mut_name<'a> {
type Ref<'t> = #ref_name<'t> where Self: 't;
type Slice<'t> = #slice_name<'t> where Self: 't;
type Iter<'t> = #iter_name<'t> where Self: 't;
type Ptr = #ptr_name;
type RefMut<'t> = #ref_mut_name<'t> where Self: 't;
type SliceMut<'t> = #slice_mut_name<'t> where Self: 't;
type IterMut<'t> = #iter_mut_name<'t> where Self: 't;
type PtrMut = #ptr_mut_name;
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn is_empty(&self) -> bool {
self.is_empty()
}
#[inline]
fn as_slice<'c>(&'c self) -> Self::Slice<'c> {
self.as_slice()
}
#[inline]
fn slice<'c, 'b: 'c>(&'c self, index: impl core::ops::RangeBounds<usize>) -> Self::Slice<'c> where Self: 'b {
#resolve_range
self.index(start..end)
}
#[inline]
fn get<'c>(&'c self, index: usize) -> Option<Self::Ref<'c>> {
self.get(index)
}
#[inline]
fn index<'c>(&'c self, index: usize) -> Self::Ref<'c> {
self.index(index)
}
#[inline]
fn iter<'c>(&'c self) -> Self::Iter<'c> {
self.as_ref().into_iter()
}
#[inline]
fn as_mut_slice<'c: 'b, 'b>(&'c mut self) -> Self::SliceMut<'c> where Self: 'b {
self.reborrow()
}
#[inline]
fn slice_mut<'c>(&'c mut self, index: impl core::ops::RangeBounds<usize>) -> Self::SliceMut<'c> {
#resolve_range
self.index_mut(start..end)
}
#[inline]
fn get_mut<'c>(&'c mut self, index: usize) -> Option<Self::RefMut<'c>> {
self.get_mut(index)
}
#[inline]
fn index_mut<'c>(&'c mut self, index: usize) -> Self::RefMut<'c> {
self.index_mut(index)
}
#[inline]
fn iter_mut<'c>(&'c mut self) -> Self::IterMut<'c> {
self.iter_mut()
}
#[inline]
fn apply_index(&mut self, indices: &[usize]) {
let _ = ::layout::__validate_permutation(indices, self.len());
unsafe {
self.__private_apply_argsort_unchecked(indices);
}
}
#[inline]
fn as_ptr(&self) -> Self::Ptr {
self.as_ptr()
}
#[inline]
fn as_mut_ptr(&mut self) -> Self::PtrMut {
self.as_mut_ptr()
}
}
};
return generated;
}
pub fn derive_vec(input: &Input) -> TokenStream {
let name = &input.name;
let vec_name = names::vec_name(&input.name);
let slice_name = names::slice_name(name);
let slice_mut_name = names::slice_mut_name(&input.name);
let ref_name = names::ref_name(&input.name);
let ref_mut_name = names::ref_mut_name(&input.name);
let ptr_name = names::ptr_name(&input.name);
let ptr_mut_name = names::ptr_mut_name(&input.name);
let iter_name = names::iter_name(name);
let iter_mut_name = names::iter_mut_name(name);
let resolve_range = resolve_range();
let generated = quote! {
impl ::layout::SoAVec<#name> for #vec_name {
type Ref<'t> = #ref_name<'t>;
type Slice<'t> = #slice_name<'t>;
type Iter<'t> = #iter_name<'t>;
type Ptr = #ptr_name;
type RefMut<'t> = #ref_mut_name<'t>;
type SliceMut<'t> = #slice_mut_name<'t>;
type IterMut<'t> = #iter_mut_name<'t>;
type PtrMut = #ptr_mut_name;
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn is_empty(&self) -> bool {
self.is_empty()
}
#[inline]
fn as_slice<'c, 'a: 'c>(&'c self) -> Self::Slice<'c> where Self: 'a {
self.as_slice()
}
#[inline]
fn slice<'c, 'a: 'c>(&'c self, index: impl core::ops::RangeBounds<usize>) -> Self::Slice<'c> where Self: 'a {
#resolve_range
self.index(start..end)
}
#[inline]
fn get<'c>(&'c self, index: usize) -> Option<Self::Ref<'c>> {
self.get(index)
}
#[inline]
fn index<'c>(&'c self, index: usize) -> Self::Ref<'c> {
self.index(index)
}
#[inline]
fn iter<'c>(&'c self) -> Self::Iter<'c> {
self.iter()
}
#[inline]
fn as_mut_slice<'c, 'a: 'c>(&'c mut self) -> Self::SliceMut<'c> where Self: 'a {
self.as_mut_slice()
}
#[inline]
fn slice_mut<'c>(&'c mut self, index: impl core::ops::RangeBounds<usize>) -> Self::SliceMut<'c> {
#resolve_range
self.index_mut(start..end)
}
#[inline]
fn get_mut<'c>(&'c mut self, index: usize) -> Option<Self::RefMut<'c>> {
self.get_mut(index)
}
#[inline]
fn index_mut<'c>(&'c mut self, index: usize) -> Self::RefMut<'c> {
self.index_mut(index)
}
#[inline]
fn iter_mut<'c>(&'c mut self) -> Self::IterMut<'c> {
self.iter_mut()
}
#[inline]
fn apply_index(&mut self, indices: &[usize]) {
use ::layout::SoASliceMut;
self.as_mut_slice().apply_index(indices);
}
#[inline]
fn new() -> Self {
#vec_name::new()
}
#[inline]
fn with_capacity(capacity: usize) -> Self {
#vec_name::with_capacity(capacity)
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn reserve(&mut self, additional: usize) {
self.reserve(additional);
}
#[inline]
fn reserve_exact(&mut self, additional: usize) {
self.reserve_exact(additional);
}
#[inline]
fn shrink_to_fit(&mut self) {
self.shrink_to_fit();
}
#[inline]
fn truncate(&mut self, len: usize) {
self.truncate(len);
}
#[inline]
fn push(&mut self, value: #name) {
self.push(value);
}
#[inline]
fn swap_remove(&mut self, index: usize) -> #name {
self.swap_remove(index)
}
#[inline]
fn insert(&mut self, index: usize, element: #name) {
self.insert(index, element);
}
#[inline]
fn replace(&mut self, index: usize, element: #name) -> #name {
self.replace(index, element)
}
#[inline]
fn remove(&mut self, index: usize) -> #name {
self.remove(index)
}
#[inline]
fn pop(&mut self) -> Option<#name> {
self.pop()
}
#[inline]
fn append(&mut self, other: &mut Self) {
self.append(other);
}
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn split_off(&mut self, at: usize) -> Self {
self.split_off(at)
}
#[inline]
fn as_ptr(&self) -> Self::Ptr {
self.as_ptr()
}
#[inline]
fn as_mut_ptr(&mut self) -> Self::PtrMut {
self.as_mut_ptr()
}
}
};
return generated;
}