use core::marker::PhantomData;
use crate::core::*;
use crate::sys;
use flecs_ecs_derive::tuples;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[doc(hidden)]
pub struct IsAnyArray {
pub a_ref: bool, pub a_row: bool, }
#[cfg(feature = "flecs_safety_locks")]
#[derive(Debug, Clone, Copy, Default)]
pub struct TableColumnSafety {
pub component_id: u64,
pub table_record: *const sys::ecs_table_record_t,
}
pub struct ComponentsData<T: QueryTuple, const LEN: usize> {
pub array_components: [*mut u8; LEN],
pub is_ref_array_components: [bool; LEN],
pub is_row_array_components: [bool; LEN],
pub index_array_components: [i8; LEN],
#[cfg(feature = "flecs_safety_locks")]
pub safety_table_records: [TableColumnSafety; LEN],
_marker: PhantomData<T>,
}
pub trait ComponentPointers<T: QueryTuple> {
fn new(iter: &sys::ecs_iter_t) -> (IsAnyArray, Self);
fn get_tuple(&mut self, index: usize) -> T::TupleType<'_>;
fn get_tuple_with_row(
&mut self,
iter: &sys::ecs_iter_t,
index_row_entity: usize,
) -> T::TupleType<'_>;
fn get_tuple_with_ref(&mut self, index: usize) -> T::TupleType<'_>;
#[cfg(feature = "flecs_safety_locks")]
fn safety_table_records(&self) -> &[TableColumnSafety];
}
impl<T: QueryTuple, const LEN: usize> ComponentPointers<T> for ComponentsData<T, LEN> {
fn new(iter: &sys::ecs_iter_t) -> (IsAnyArray, Self) {
let mut array_components = [core::ptr::null::<u8>() as *mut u8; LEN];
let mut is_ref_array_components = [false; LEN];
let mut is_row_array_components = [false; LEN];
let mut index_array_components = [0; LEN];
#[cfg(feature = "flecs_safety_locks")]
let mut safety_table_records = [TableColumnSafety::default(); LEN];
let is_any_array = if (iter.ref_fields | iter.up_fields) != 0 {
T::populate_array_ptrs(
iter,
&mut array_components[..],
&mut is_ref_array_components[..],
&mut is_row_array_components[..],
&mut index_array_components[..],
#[cfg(feature = "flecs_safety_locks")]
&mut safety_table_records[..],
)
} else {
T::populate_self_array_ptrs(
iter,
&mut array_components[..],
#[cfg(feature = "flecs_safety_locks")]
&mut safety_table_records[..],
);
IsAnyArray {
a_ref: false,
a_row: false,
}
};
(
is_any_array,
Self {
array_components,
is_ref_array_components,
is_row_array_components,
index_array_components,
#[cfg(feature = "flecs_safety_locks")]
safety_table_records,
_marker: PhantomData::<T>,
},
)
}
#[inline(always)]
fn get_tuple(&mut self, index: usize) -> T::TupleType<'_> {
T::create_tuple(&self.array_components[..], index)
}
fn get_tuple_with_row(
&mut self,
iter: &sys::ecs_iter_t,
index_row_entity: usize,
) -> T::TupleType<'_> {
T::create_tuple_with_row(
iter,
&mut self.array_components[..],
&self.is_ref_array_components[..],
&self.is_row_array_components[..],
&self.index_array_components[..],
index_row_entity,
)
}
fn get_tuple_with_ref(&mut self, index: usize) -> T::TupleType<'_> {
T::create_tuple_with_ref(
&self.array_components[..],
&self.is_ref_array_components[..],
index,
)
}
#[cfg(feature = "flecs_safety_locks")]
fn safety_table_records(&self) -> &[TableColumnSafety] {
&self.safety_table_records[..]
}
}
pub trait IterableTypeOperation {
type CastType;
type ActualType<'w>;
type SliceType<'w>;
type OnlyType: ComponentOrPairId;
type OnlyPairType: ComponentId;
const IS_IMMUTABLE: bool;
const IS_OPTIONAL: bool;
fn populate_term(term: &mut sys::ecs_term_t);
fn create_tuple_data<'a>(array_components_data: *mut u8, index: usize) -> Self::ActualType<'a>;
fn create_tuple_with_ref_data<'a>(
array_components_data: *mut u8,
is_ref: bool,
index: usize,
) -> Self::ActualType<'a>;
}
impl<T> IterableTypeOperation for &T
where
T: ComponentOrPairId,
{
type CastType = *const <T as ComponentOrPairId>::CastType;
type ActualType<'w> = &'w <T as ComponentOrPairId>::CastType;
type SliceType<'w> = &'w [<T as ComponentOrPairId>::CastType];
type OnlyType = T;
type OnlyPairType = <T as ComponentOrPairId>::CastType;
const IS_IMMUTABLE: bool = true;
const IS_OPTIONAL: bool = false;
#[inline(always)]
fn populate_term(term: &mut sys::ecs_term_t) {
term.inout = InOutKind::In as i16;
}
#[inline(always)]
fn create_tuple_data<'a>(array_components_data: *mut u8, index: usize) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
unsafe { &*data_ptr.add(index) }
}
#[inline(always)]
fn create_tuple_with_ref_data<'a>(
array_components_data: *mut u8,
is_ref: bool,
index: usize,
) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
unsafe {
if is_ref {
&*data_ptr.add(0)
} else {
&*data_ptr.add(index)
}
}
}
}
impl<T> IterableTypeOperation for &mut T
where
T: ComponentOrPairId,
{
type CastType = *mut <T as ComponentOrPairId>::CastType;
type ActualType<'w> = &'w mut <T as ComponentOrPairId>::CastType;
type SliceType<'w> = &'w mut [<T as ComponentOrPairId>::CastType];
type OnlyType = T;
type OnlyPairType = <T as ComponentOrPairId>::CastType;
const IS_IMMUTABLE: bool = false;
const IS_OPTIONAL: bool = false;
#[inline(always)]
fn populate_term(term: &mut sys::ecs_term_t) {
term.inout = InOutKind::InOut as i16;
}
#[inline(always)]
fn create_tuple_data<'a>(array_components_data: *mut u8, index: usize) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
unsafe { &mut *data_ptr.add(index) }
}
#[inline(always)]
fn create_tuple_with_ref_data<'a>(
array_components_data: *mut u8,
is_ref: bool,
index: usize,
) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
unsafe {
if is_ref {
&mut *data_ptr.add(0)
} else {
&mut *data_ptr.add(index)
}
}
}
}
impl<T> IterableTypeOperation for Option<&T>
where
T: ComponentOrPairId,
{
type CastType = *const <T as ComponentOrPairId>::CastType;
type ActualType<'w> = Option<&'w <T as ComponentOrPairId>::CastType>;
type SliceType<'w> = Option<&'w [<T as ComponentOrPairId>::CastType]>;
type OnlyType = T;
type OnlyPairType = <T as ComponentOrPairId>::CastType;
const IS_IMMUTABLE: bool = true;
const IS_OPTIONAL: bool = true;
fn populate_term(term: &mut sys::ecs_term_t) {
term.inout = InOutKind::In as i16;
term.oper = OperKind::Optional as i16;
}
#[inline(always)]
fn create_tuple_data<'a>(array_components_data: *mut u8, index: usize) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
if data_ptr.is_null() {
None
} else {
Some(unsafe { &*data_ptr.add(index) })
}
}
#[inline(always)]
fn create_tuple_with_ref_data<'a>(
array_components_data: *mut u8,
is_ref: bool,
index: usize,
) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
if data_ptr.is_null() {
None
} else if is_ref {
Some(unsafe { &*data_ptr.add(0) })
} else {
Some(unsafe { &*data_ptr.add(index) })
}
}
}
impl<T> IterableTypeOperation for Option<&mut T>
where
T: ComponentOrPairId,
{
type CastType = *mut <T as ComponentOrPairId>::CastType;
type ActualType<'w> = Option<&'w mut <T as ComponentOrPairId>::CastType>;
type SliceType<'w> = Option<&'w mut [<T as ComponentOrPairId>::CastType]>;
type OnlyType = T;
type OnlyPairType = <T as ComponentOrPairId>::CastType;
const IS_IMMUTABLE: bool = false;
const IS_OPTIONAL: bool = true;
#[inline(always)]
fn populate_term(term: &mut sys::ecs_term_t) {
term.inout = InOutKind::InOut as i16;
term.oper = OperKind::Optional as i16;
}
#[inline(always)]
fn create_tuple_data<'a>(array_components_data: *mut u8, index: usize) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
if data_ptr.is_null() {
None
} else {
Some(unsafe { &mut *data_ptr.add(index) })
}
}
#[inline(always)]
fn create_tuple_with_ref_data<'a>(
array_components_data: *mut u8,
is_ref: bool,
index: usize,
) -> Self::ActualType<'a> {
let data_ptr = array_components_data as Self::CastType;
if data_ptr.is_null() {
None
} else if is_ref {
Some(unsafe { &mut *data_ptr.add(0) })
} else {
Some(unsafe { &mut *data_ptr.add(index) })
}
}
}
pub trait QueryTuple: Sized {
type Pointers: ComponentPointers<Self>;
type TupleType<'a>;
const CONTAINS_ANY_TAG_TERM: bool;
const COUNT: i32;
const COUNT_IMMUTABLE: usize;
const COUNT_MUTABLE: usize;
const COUNT_OPTIONAL_IMMUTABLE: usize;
const COUNT_OPTIONAL_MUTABLE: usize;
fn create_ptrs(iter: &sys::ecs_iter_t) -> (IsAnyArray, Self::Pointers) {
Self::Pointers::new(iter)
}
fn populate<'a>(query: &mut impl QueryBuilderImpl<'a>);
#[inline(always)]
fn register_ids_descriptor(world: *mut sys::ecs_world_t, desc: &mut sys::ecs_query_desc_t) {
Self::register_ids_descriptor_at(world, &mut desc.terms[..], &mut 0);
}
fn register_ids_descriptor_at(
world: *mut sys::ecs_world_t,
terms: &mut [sys::ecs_term_t],
index: &mut usize,
);
fn populate_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
is_ref: &mut [bool],
is_row: &mut [bool],
indexes: &mut [i8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
) -> IsAnyArray;
fn populate_self_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
);
fn create_tuple(array_components: &[*mut u8], index: usize) -> Self::TupleType<'_>;
fn create_tuple_with_ref<'a>(
array_components: &'a [*mut u8],
is_ref_array_components: &[bool],
index: usize,
) -> Self::TupleType<'a>;
fn create_tuple_with_row<'a>(
iter: &sys::ecs_iter_t,
array_components: &'a mut [*mut u8],
is_ref_array_components: &[bool],
is_row_array_components: &[bool],
indexes_array_components: &[i8],
index_row_entity: usize,
) -> Self::TupleType<'a>;
}
#[rustfmt::skip]
impl<A> QueryTuple for A
where
A: IterableTypeOperation,
{
type Pointers = ComponentsData<A, 1>;
type TupleType<'w> = A::ActualType<'w>;
const CONTAINS_ANY_TAG_TERM: bool = <<A::OnlyPairType as ComponentId>::UnderlyingType as ComponentInfo>::IS_TAG;
const COUNT : i32 = 1;
const COUNT_IMMUTABLE: usize = if A::IS_IMMUTABLE && !A::IS_OPTIONAL { 1 } else { 0 };
const COUNT_MUTABLE: usize = if !A::IS_IMMUTABLE && !A::IS_OPTIONAL { 1 } else { 0 };
const COUNT_OPTIONAL_IMMUTABLE: usize = if A::IS_IMMUTABLE && A::IS_OPTIONAL { 1 } else { 0 };
const COUNT_OPTIONAL_MUTABLE: usize = if !A::IS_IMMUTABLE && A::IS_OPTIONAL { 1 } else { 0 };
#[inline(always)]
fn populate<'a>(query: &mut impl QueryBuilderImpl<'a>) {
let _world_ptr = query.world_ptr();
let id = <A::OnlyType as ComponentOrPairId>::get_id(query.world());
if <A::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(_world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}
query.with(id);
let term = query.current_term_mut();
A::populate_term(term);
}
#[expect(
clippy::not_unsafe_ptr_arg_deref,
reason = "x"
)]
#[inline(always)]
fn register_ids_descriptor_at(
world: *mut sys::ecs_world_t,
terms: &mut [sys::ecs_term_t],
index: &mut usize,
) {
let world = unsafe { WorldRef::from_ptr(world) };
terms[*index].id = <A::OnlyType as ComponentOrPairId>::get_id(world);
A::populate_term(&mut terms[*index]);
*index += 1;
}
#[inline(always)]
fn populate_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
is_ref: &mut [bool],
is_row: &mut [bool],
indexes: &mut [i8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
) -> IsAnyArray {
#[cfg(feature = "flecs_safety_locks")]
let tr = unsafe { table_records.get_unchecked_mut(0) };
#[cfg(feature = "flecs_safety_locks")]
{
tr.table_record = unsafe { *it.trs.add(0) };
}
#[cfg(not(feature = "flecs_term_count_64"))]
let val = 1u32 << 0;
#[cfg(feature = "flecs_term_count_64")]
let val = 1u64 << 0;
if it.row_fields & val != 0 {
is_ref[0] = true;
is_row[0] = true;
indexes[0] = 0;
#[cfg(feature = "flecs_safety_locks")]
{
tr.component_id = unsafe { *it.ids.add(0) };
}
} else {
components[0] = flecs_field::<A::OnlyPairType>(it, 0) as *mut u8 ;
is_ref[0] = unsafe { *it.sources.add(0) != 0 };
};
IsAnyArray {
a_ref: is_ref[0],
a_row: is_row[0],
}
}
#[inline(always)]
fn populate_self_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
) {
#[cfg(feature = "flecs_safety_locks")]
{
let tr = unsafe { table_records.get_unchecked_mut(0) };
tr.table_record = unsafe { *it.trs.add(0) };
}
components[0] = flecs_field::<A::OnlyPairType>(it, 0) as *mut u8 ;
}
#[inline(always)]
fn create_tuple(array_components: &[*mut u8], index: usize) -> Self::TupleType<'_> {
A::create_tuple_data(unsafe { *array_components.get_unchecked(0) }, index)
}
fn create_tuple_with_ref<'a>(
array_components: &'a [*mut u8],
is_ref_array_components: &[bool],
index: usize
) -> Self::TupleType<'a> {
A::create_tuple_with_ref_data(array_components[0], is_ref_array_components[0], index)
}
#[inline(always)]
fn create_tuple_with_row<'a>(
iter: &sys::ecs_iter_t,
array_components: &'a mut [*mut u8],
is_ref_array_components: &[bool],
is_row_array_components: &[bool],
indexes_array_components: &[i8],
index_row_entity: usize
) -> Self::TupleType<'a> {
if is_row_array_components[0] {
let ptr_to_first_index_array = &mut array_components[0];
*ptr_to_first_index_array = unsafe { flecs_field_at::<A::OnlyPairType>(iter, *indexes_array_components.get_unchecked(0), index_row_entity as i32) } as *mut u8;
}
A::create_tuple_with_ref_data(
array_components[0],
is_ref_array_components[0],
index_row_entity,
)
}
}
macro_rules! tuple_count {
() => { 0 };
($head:ident) => { 1 };
($head:ident, $($tail:ident),*) => { 1 + tuple_count!($($tail),*) };
}
macro_rules! impl_iterable {
($($t:ident),*) => {
impl<$($t: IterableTypeOperation),*> QueryTuple for ($($t,)*) {
type TupleType<'w> = ($(
$t::ActualType<'w>,
)*);
const CONTAINS_ANY_TAG_TERM: bool = $(<<$t::OnlyPairType as ComponentId>::UnderlyingType as ComponentInfo>::IS_TAG ||)* false;
type Pointers = ComponentsData<Self, { tuple_count!($($t),*) }>;
const COUNT : i32 = tuple_count!($($t),*);
const COUNT_IMMUTABLE: usize = $((if $t::IS_IMMUTABLE && !$t::IS_OPTIONAL { 1 } else { 0 }) +)* 0;
const COUNT_MUTABLE: usize = $((if !$t::IS_IMMUTABLE && !$t::IS_OPTIONAL { 1 } else { 0 }) +)* 0;
const COUNT_OPTIONAL_IMMUTABLE: usize = $((if $t::IS_IMMUTABLE && $t::IS_OPTIONAL { 1 } else { 0 }) +)* 0;
const COUNT_OPTIONAL_MUTABLE: usize = $((if !$t::IS_IMMUTABLE && $t::IS_OPTIONAL { 1 } else { 0 }) +)* 0;
#[inline(always)]
fn populate<'a>(query: &mut impl QueryBuilderImpl<'a>) {
let _world = query.world();
let _world_ptr = query.world_ptr();
$(
let id = <$t::OnlyType as ComponentOrPairId>::get_id(_world);
if <$t::OnlyType as ComponentOrPairId>::IS_PAIR {
ecs_assert!(
unsafe { sys::ecs_get_typeid(_world_ptr, id) } != 0,
FlecsErrorCode::InvalidOperation,
"Pair is not a (data) component. Possible cause: PairIsTag trait"
);
}
query.with(id);
let term = query.current_term_mut();
$t::populate_term(term);
)*
}
#[allow(unused)]
#[inline(always)]
fn register_ids_descriptor_at(world: *mut sys::ecs_world_t, terms: &mut [sys::ecs_term_t], index: &mut usize) {
$( $t::register_ids_descriptor_at(world, terms, index); )*
}
#[allow(unused)]
#[inline(always)]
fn populate_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
is_ref: &mut [bool],
is_row: &mut [bool],
indexes: &mut [i8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
) -> IsAnyArray {
let mut index : usize = 0;
let mut any_ref = false;
let mut any_row = false;
#[cfg(feature = "flecs_safety_locks")]
let mut index_immutable : usize = 0;
#[cfg(feature = "flecs_safety_locks")]
let mut index_mutable : usize = const { Self::COUNT_IMMUTABLE };
#[cfg(feature = "flecs_safety_locks")]
let mut index_optional_immutable : usize = const { Self::COUNT_IMMUTABLE + Self::COUNT_MUTABLE };
#[cfg(feature = "flecs_safety_locks")]
let mut index_optional_mutable : usize = const { Self::COUNT_IMMUTABLE + Self::COUNT_MUTABLE + Self::COUNT_OPTIONAL_IMMUTABLE };
$(
#[cfg(feature = "flecs_safety_locks")]
let idx = match ($t::IS_IMMUTABLE, $t::IS_OPTIONAL) {
(true, false) => &mut index_immutable,
(true, true) => &mut index_optional_immutable,
(false, false) => &mut index_mutable,
(false, true) => &mut index_optional_mutable,
};
#[cfg(feature = "flecs_safety_locks")]
let tr = unsafe { table_records.get_unchecked_mut(*idx) };
#[cfg(feature = "flecs_safety_locks")]
{
tr.table_record = unsafe { *it.trs.add(index) };
}
#[cfg(feature = "flecs_safety_locks")]
{
*idx += 1;
}
#[cfg(not(feature = "flecs_term_count_64"))]
let val = 1u32 << index;
#[cfg(feature = "flecs_term_count_64")]
let val = 1u64 << index;
if (it.row_fields & val) != 0 {
is_ref[index] = true;
is_row[index] = true;
indexes[index] = index as i8;
any_ref |= true;
any_row |= true;
#[cfg(feature = "flecs_safety_locks")]
{
tr.component_id = unsafe { *it.ids.add(index) };
}
} else {
components[index] =
flecs_field::<$t::OnlyPairType>(it, index as i8) as *mut u8;
let is_ref_val = unsafe { *it.sources.add(index ) != 0 };
is_ref[index] = is_ref_val;
any_ref |= is_ref_val;
}
index += 1;
)*
IsAnyArray {
a_ref: any_ref,
a_row: any_row,
}
}
#[allow(unused)]
#[inline(always)]
fn populate_self_array_ptrs(
it: &sys::ecs_iter_t,
components: &mut [*mut u8],
#[cfg(feature = "flecs_safety_locks")] table_records: &mut [TableColumnSafety],
) {
let mut index : usize = 0;
#[cfg(feature = "flecs_safety_locks")]
let mut index_immutable : usize = 0;
#[cfg(feature = "flecs_safety_locks")]
let mut index_mutable : usize = const { Self::COUNT_IMMUTABLE };
#[cfg(feature = "flecs_safety_locks")]
let mut index_optional_immutable : usize = const { Self::COUNT_IMMUTABLE + Self::COUNT_MUTABLE };
#[cfg(feature = "flecs_safety_locks")]
let mut index_optional_mutable : usize = const { Self::COUNT_IMMUTABLE + Self::COUNT_MUTABLE + Self::COUNT_OPTIONAL_IMMUTABLE };
$(
components[index] =
flecs_field::<$t::OnlyPairType>(it, index as i8) as *mut u8;
#[cfg(feature = "flecs_safety_locks")]
{
let idx = match ($t::IS_IMMUTABLE, $t::IS_OPTIONAL) {
(true, false) => &mut index_immutable,
(true, true) => &mut index_optional_immutable,
(false, false) => &mut index_mutable,
(false, true) => &mut index_optional_mutable,
};
let tr = unsafe { table_records.get_unchecked_mut(*idx) };
tr.table_record = unsafe { *it.trs.add(index) };
*idx += 1;
}
index += 1;
)*
}
#[allow(unused, clippy::unused_unit)]
#[inline(always)]
fn create_tuple(array_components: &[*mut u8], index: usize) -> Self::TupleType<'_> {
let mut column: usize = 0;
($({
let data_ptr = unsafe { *array_components.get_unchecked(column) };
column += 1;
$t::create_tuple_data(data_ptr, index)
},)*)
}
#[allow(unused, clippy::unused_unit)]
#[inline(always)]
fn create_tuple_with_ref<'a>(array_components: &'a [*mut u8], is_ref_array_components: &[bool], index: usize) -> Self::TupleType<'a> {
let mut column: usize = 0;
($({
let data_ptr = unsafe { *array_components.get_unchecked(column) };
let is_ref = unsafe { *is_ref_array_components.get_unchecked(column) };
column += 1;
$t::create_tuple_with_ref_data(data_ptr, is_ref, index)
},)*)
}
#[allow(unused, clippy::unused_unit)]
#[inline(always)]
fn create_tuple_with_row<'a>(
iter: &sys::ecs_iter_t,
array_components: &'a mut [*mut u8],
is_ref_array_components: &[bool],
is_row_array_components: &[bool],
indexes_array_components: &[i8],
index_row_entity: usize
) -> Self::TupleType<'a> {
let mut column: usize = 0;
($({
let is_row = unsafe { *is_row_array_components.get_unchecked(column) };
if is_row {
let ptr_to_first_index_array = unsafe { &mut *array_components.get_unchecked_mut(column) };
let index_array_component = unsafe { *indexes_array_components.get_unchecked(column) };
*ptr_to_first_index_array = unsafe { flecs_field_at::<$t::OnlyPairType>(iter, index_array_component, index_row_entity as i32) } as *mut $t::OnlyPairType as *mut u8;
}
let data_ptr = unsafe { *array_components.get_unchecked(column) };
let is_ref = unsafe { *is_ref_array_components.get_unchecked(column) };
column += 1;
$t::create_tuple_with_ref_data(data_ptr, is_ref, index_row_entity)
},)*)
}
}
}
}
tuples!(impl_iterable, 0, 32);