melior/ir/attribute/
array.rs1use super::{Attribute, AttributeLike};
2use crate::{Context, Error};
3use mlir_sys::{
4 mlirArrayAttrGet, mlirArrayAttrGetElement, mlirArrayAttrGetNumElements, MlirAttribute,
5};
6
7#[derive(Clone, Copy)]
9pub struct ArrayAttribute<'c> {
10 attribute: Attribute<'c>,
11}
12
13impl<'c> ArrayAttribute<'c> {
14 pub fn new(context: &'c Context, values: &[Attribute<'c>]) -> Self {
16 unsafe {
17 Self::from_raw(mlirArrayAttrGet(
18 context.to_raw(),
19 values.len() as isize,
20 values.as_ptr() as *const _ as *const _,
21 ))
22 }
23 }
24
25 pub fn len(&self) -> usize {
27 (unsafe { mlirArrayAttrGetNumElements(self.attribute.to_raw()) }) as usize
28 }
29
30 pub fn is_empty(&self) -> bool {
32 self.len() == 0
33 }
34
35 pub fn element(&self, index: usize) -> Result<Attribute<'c>, Error> {
37 if index < self.len() {
38 Ok(unsafe {
39 Attribute::from_raw(mlirArrayAttrGetElement(
40 self.attribute.to_raw(),
41 index as isize,
42 ))
43 })
44 } else {
45 Err(Error::PositionOutOfBounds {
46 name: "array element",
47 value: self.to_string(),
48 index,
49 })
50 }
51 }
52}
53
54attribute_traits!(ArrayAttribute, is_dense_i64_array, "dense i64 array");
55
56#[cfg(test)]
57mod tests {
58 use crate::{
59 ir::{attribute::IntegerAttribute, r#type::IntegerType, Type},
60 test::create_test_context,
61 };
62
63 use super::*;
64
65 #[test]
66 fn element() {
67 let context = create_test_context();
68 let r#type = IntegerType::new(&context, 64).into();
69 let attributes = [
70 IntegerAttribute::new(r#type, 1).into(),
71 IntegerAttribute::new(r#type, 2).into(),
72 IntegerAttribute::new(r#type, 3).into(),
73 ];
74
75 let attribute = ArrayAttribute::new(&context, &attributes);
76
77 assert_eq!(attribute.element(0).unwrap(), attributes[0]);
78 assert_eq!(attribute.element(1).unwrap(), attributes[1]);
79 assert_eq!(attribute.element(2).unwrap(), attributes[2]);
80 assert!(matches!(
81 attribute.element(3),
82 Err(Error::PositionOutOfBounds { .. })
83 ));
84 }
85
86 #[test]
87 fn len() {
88 let context = create_test_context();
89 let attribute = ArrayAttribute::new(
90 &context,
91 &[IntegerAttribute::new(Type::index(&context), 1).into()],
92 );
93
94 assert_eq!(attribute.len(), 1);
95 }
96}