use std::sync::Arc;
use crate::std_extensions::collections::array::op_builder::GenericArrayOpBuilder;
use crate::{
Extension, Wire,
builder::{BuildError, Dataflow},
extension::{ExtensionId, SignatureError, TypeDef},
ops::constant::ValueName,
types::{CustomType, Type, TypeArg, TypeName},
};
pub trait ArrayKind:
Clone
+ Copy
+ std::fmt::Debug
+ std::fmt::Display
+ Eq
+ PartialEq
+ Default
+ Send
+ Sync
+ 'static
{
const EXTENSION_ID: ExtensionId;
const TYPE_NAME: TypeName;
const VALUE_NAME: ValueName;
fn extension() -> &'static Arc<Extension>;
fn type_def() -> &'static TypeDef;
fn instantiate_custom_ty(
array_def: &TypeDef,
size: impl Into<TypeArg>,
element_ty: impl Into<TypeArg>,
) -> Result<CustomType, SignatureError> {
array_def.instantiate(vec![size.into(), element_ty.into()])
}
fn instantiate_ty(
array_def: &TypeDef,
size: impl Into<TypeArg>,
element_ty: impl Into<TypeArg>,
) -> Result<Type, SignatureError> {
Self::instantiate_custom_ty(array_def, size, element_ty).map(Into::into)
}
fn custom_ty(size: impl Into<TypeArg>, element_ty: impl Into<TypeArg>) -> CustomType {
Self::instantiate_custom_ty(Self::type_def(), size, element_ty)
.expect("array parameters are valid")
}
#[must_use]
fn ty(size: u64, element_ty: Type) -> Type {
Self::custom_ty(size, element_ty).into()
}
fn ty_parametric(
size: impl Into<TypeArg>,
element_ty: impl Into<TypeArg>,
) -> Result<Type, SignatureError> {
Self::instantiate_ty(Self::type_def(), size, element_ty)
}
fn build_clone<D: Dataflow>(
builder: &mut D,
elem_ty: Type,
size: u64,
arr: Wire,
) -> Result<(Wire, Wire), BuildError> {
builder.add_generic_array_clone::<Self>(elem_ty, size, arr)
}
fn build_discard<D: Dataflow>(
builder: &mut D,
elem_ty: Type,
size: u64,
arr: Wire,
) -> Result<(), BuildError> {
builder.add_generic_array_discard::<Self>(elem_ty, size, arr)
}
}