soa_derive_internal 0.14.0

Internal implementation crate for soa-derive
Documentation
use proc_macro2::TokenStream;
use quote::quote;

use crate::input::Input;
use crate::names;


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 generated = quote! {
        impl<'a> ::soa_derive::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 {
                let start = match index.start_bound() {
                    std::ops::Bound::Included(i) | std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => 0,
                };
                let n = self.len();
                let end = match index.end_bound() {
                    std::ops::Bound::Included(i) => (*i + 1).min(n),
                    std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => n,
                };
                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 generated = quote! {

        impl<'a> ::soa_derive::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;

            fn len(&self) -> usize {
                self.len()
            }

            fn is_empty(&self) -> bool {
                self.is_empty()
            }

            fn as_slice<'c>(&'c self) -> Self::Slice<'c> {
                self.as_slice()
            }

            fn slice<'c, 'b: 'c>(&'c self, index: impl core::ops::RangeBounds<usize>) -> Self::Slice<'c> where Self: 'b {
                let start = match index.start_bound() {
                    std::ops::Bound::Included(i) | std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => 0,
                };
                let n = self.len();
                let end = match index.end_bound() {
                    std::ops::Bound::Included(i) => (*i + 1).min(n),
                    std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => n,
                };
                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.as_ref().into_iter()
            }

            fn as_mut_slice<'c: 'b, 'b>(&'c mut self) -> Self::SliceMut<'c> where Self: 'b {
                self.reborrow()
            }

            fn slice_mut<'c>(&'c mut self, index: impl core::ops::RangeBounds<usize>) -> Self::SliceMut<'c> {
                let start = match index.start_bound() {
                    std::ops::Bound::Included(i) | std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => 0,
                };
                let n = self.len();
                let end = match index.end_bound() {
                    std::ops::Bound::Included(i) => (*i + 1).min(n),
                    std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => n,
                };
                self.index_mut(start..end)
            }

            fn get_mut<'c>(&'c mut self, index: usize) -> Option<Self::RefMut<'c>> {
                self.get_mut(index)
            }

            fn index_mut<'c>(&'c mut self, index: usize) -> Self::RefMut<'c> {
                self.index_mut(index)
            }

            fn iter_mut<'c>(&'c mut self) -> Self::IterMut<'c> {
                self.iter_mut()
            }

            fn apply_index(&mut self, indices: &[usize]) {
                self.__private_apply_permutation(&mut ::soa_derive::Permutation::oneline(indices).inverse());
            }

            fn as_ptr(&self) -> Self::Ptr {
                self.as_ptr()
            }

            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 generated = quote! {

        impl ::soa_derive::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;

            fn len(&self) -> usize {
                self.len()
            }

            fn is_empty(&self) -> bool {
                self.is_empty()
            }

            fn as_slice<'c, 'a: 'c>(&'c self) -> Self::Slice<'c> where Self: 'a {
                self.as_slice()
            }

            fn slice<'c, 'a: 'c>(&'c self, index: impl core::ops::RangeBounds<usize>) -> Self::Slice<'c> where Self: 'a {
                let start = match index.start_bound() {
                    std::ops::Bound::Included(i) | std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => 0,
                };
                let n = self.len();
                let end = match index.end_bound() {
                    std::ops::Bound::Included(i) => (*i + 1).min(n),
                    std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => n,
                };
                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_mut_slice<'c, 'a: 'c>(&'c mut self) -> Self::SliceMut<'c> where Self: 'a {
                self.as_mut_slice()
            }

            fn slice_mut<'c>(&'c mut self, index: impl core::ops::RangeBounds<usize>) -> Self::SliceMut<'c> {
                let start = match index.start_bound() {
                    std::ops::Bound::Included(i) | std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => 0,
                };
                let n = self.len();
                let end = match index.end_bound() {
                    std::ops::Bound::Included(i) => (*i + 1).min(n),
                    std::ops::Bound::Excluded(i) => *i,
                    std::ops::Bound::Unbounded => n,
                };
                self.index_mut(start..end)
            }

            fn get_mut<'c>(&'c mut self, index: usize) -> Option<Self::RefMut<'c>> {
                self.get_mut(index)
            }

            fn index_mut<'c>(&'c mut self, index: usize) -> Self::RefMut<'c> {
                self.index_mut(index)
            }

            fn iter_mut<'c>(&'c mut self) -> Self::IterMut<'c> {
                self.iter_mut()
            }

            fn apply_index(&mut self, indices: &[usize]) {
                use ::soa_derive::SoASliceMut;
                self.as_mut_slice().apply_index(indices);
            }

            fn new() -> Self {
                Self::new()
            }

            fn with_capacity(capacity: usize) -> Self {
                Self::with_capacity(capacity)
            }

            fn capacity(&self) -> usize {
                self.capacity()
            }

            fn reserve(&mut self, additional: usize) {
                self.reserve(additional);
            }

            fn reserve_exact(&mut self, additional: usize) {
                self.reserve_exact(additional);
            }

            fn shrink_to_fit(&mut self) {
                self.shrink_to_fit();
            }

            fn truncate(&mut self, len: usize) {
                self.truncate(len);
            }

            fn push(&mut self, value: #name) {
                self.push(value);
            }

            fn swap_remove(&mut self, index: usize) -> #name {
                self.swap_remove(index)
            }

            fn insert(&mut self, index: usize, element: #name) {
                self.insert(index, element);
            }

            fn replace(&mut self, index: usize, element: #name) -> #name {
                self.replace(index, element)
            }

            fn remove(&mut self, index: usize) -> #name {
                self.remove(index)
            }

            fn pop(&mut self) -> Option<#name> {
                self.pop()
            }

            fn append(&mut self, other: &mut Self) {
                self.append(other);
            }

            fn clear(&mut self) {
                self.clear();
            }

            fn split_off(&mut self, at: usize) -> Self {
                self.split_off(at)
            }

            fn as_ptr(&self) -> Self::Ptr {
                self.as_ptr()
            }

            fn as_mut_ptr(&mut self) -> Self::PtrMut {
                self.as_mut_ptr()
            }
        }
    };

    return generated
}