@@ -15,14 +15,15 @@ use std::sync::Arc;
1515use delegate:: delegate;
1616use lazy_static:: lazy_static;
1717
18+ use crate :: builder:: { BuildError , Dataflow } ;
1819use crate :: extension:: resolution:: { ExtensionResolutionError , WeakExtensionRegistry } ;
19- use crate :: extension:: simple_op:: { MakeOpDef , MakeRegisteredOp } ;
20+ use crate :: extension:: simple_op:: { HasConcrete , MakeOpDef , MakeRegisteredOp } ;
2021use crate :: extension:: { ExtensionId , ExtensionSet , SignatureError , TypeDef , TypeDefBound } ;
2122use crate :: ops:: constant:: { CustomConst , ValueName } ;
2223use crate :: ops:: { ExtensionOp , OpName } ;
2324use crate :: types:: type_param:: { TypeArg , TypeParam } ;
2425use crate :: types:: { CustomCheckFailure , Type , TypeBound , TypeName } ;
25- use crate :: Extension ;
26+ use crate :: { Extension , Wire } ;
2627
2728pub use array_clone:: { GenericArrayClone , GenericArrayCloneDef , ARRAY_CLONE_OP_ID } ;
2829pub use array_conversion:: { Direction , GenericArrayConvert , GenericArrayConvertDef , FROM , INTO } ;
@@ -32,7 +33,8 @@ pub use array_op::{GenericArrayOp, GenericArrayOpDef};
3233pub use array_repeat:: { GenericArrayRepeat , GenericArrayRepeatDef , ARRAY_REPEAT_OP_ID } ;
3334pub use array_scan:: { GenericArrayScan , GenericArrayScanDef , ARRAY_SCAN_OP_ID } ;
3435pub use array_value:: GenericArrayValue ;
35- pub use op_builder:: ArrayOpBuilder ;
36+
37+ use op_builder:: GenericArrayOpBuilder ;
3638
3739/// Reported unique name of the array type.
3840pub const ARRAY_TYPENAME : TypeName = TypeName :: new_inline ( "array" ) ;
@@ -170,6 +172,236 @@ pub fn new_array_op(element_ty: Type, size: u64) -> ExtensionOp {
170172 op. to_extension_op ( ) . unwrap ( )
171173}
172174
175+ /// Trait for building array operations in a dataflow graph.
176+ pub trait ArrayOpBuilder : GenericArrayOpBuilder {
177+ /// Adds a new array operation to the dataflow graph and return the wire
178+ /// representing the new array.
179+ ///
180+ /// # Arguments
181+ ///
182+ /// * `elem_ty` - The type of the elements in the array.
183+ /// * `values` - An iterator over the values to initialize the array with.
184+ ///
185+ /// # Errors
186+ ///
187+ /// If building the operation fails.
188+ ///
189+ /// # Returns
190+ ///
191+ /// The wire representing the new array.
192+ fn add_new_array (
193+ & mut self ,
194+ elem_ty : Type ,
195+ values : impl IntoIterator < Item = Wire > ,
196+ ) -> Result < Wire , BuildError > {
197+ self . add_new_generic_array :: < Array > ( elem_ty, values)
198+ }
199+
200+ /// Adds an array clone operation to the dataflow graph and return the wires
201+ /// representing the originala and cloned array.
202+ ///
203+ /// # Arguments
204+ ///
205+ /// * `elem_ty` - The type of the elements in the array.
206+ /// * `size` - The size of the array.
207+ /// * `input` - The wire representing the array.
208+ ///
209+ /// # Errors
210+ ///
211+ /// If building the operation fails.
212+ ///
213+ /// # Returns
214+ ///
215+ /// The wires representing the original and cloned array.
216+ fn add_array_clone (
217+ & mut self ,
218+ elem_ty : Type ,
219+ size : u64 ,
220+ input : Wire ,
221+ ) -> Result < ( Wire , Wire ) , BuildError > {
222+ self . add_generic_array_clone :: < Array > ( elem_ty, size, input)
223+ }
224+
225+ /// Adds an array discard operation to the dataflow graph.
226+ ///
227+ /// # Arguments
228+ ///
229+ /// * `elem_ty` - The type of the elements in the array.
230+ /// * `size` - The size of the array.
231+ /// * `input` - The wire representing the array.
232+ ///
233+ /// # Errors
234+ ///
235+ /// If building the operation fails.
236+ fn add_array_discard (
237+ & mut self ,
238+ elem_ty : Type ,
239+ size : u64 ,
240+ input : Wire ,
241+ ) -> Result < ( ) , BuildError > {
242+ self . add_generic_array_discard :: < Array > ( elem_ty, size, input)
243+ }
244+
245+ /// Adds an array get operation to the dataflow graph.
246+ ///
247+ /// # Arguments
248+ ///
249+ /// * `elem_ty` - The type of the elements in the array.
250+ /// * `size` - The size of the array.
251+ /// * `input` - The wire representing the array.
252+ /// * `index` - The wire representing the index to get.
253+ ///
254+ /// # Errors
255+ ///
256+ /// If building the operation fails.
257+ ///
258+ /// # Returns
259+ ///
260+ /// * The wire representing the value at the specified index in the array
261+ /// * The wire representing the array
262+ fn add_array_get (
263+ & mut self ,
264+ elem_ty : Type ,
265+ size : u64 ,
266+ input : Wire ,
267+ index : Wire ,
268+ ) -> Result < ( Wire , Wire ) , BuildError > {
269+ self . add_generic_array_get :: < Array > ( elem_ty, size, input, index)
270+ }
271+
272+ /// Adds an array set operation to the dataflow graph.
273+ ///
274+ /// This operation sets the value at a specified index in the array.
275+ ///
276+ /// # Arguments
277+ ///
278+ /// * `elem_ty` - The type of the elements in the array.
279+ /// * `size` - The size of the array.
280+ /// * `input` - The wire representing the array.
281+ /// * `index` - The wire representing the index to set.
282+ /// * `value` - The wire representing the value to set at the specified index.
283+ ///
284+ /// # Errors
285+ ///
286+ /// Returns an error if building the operation fails.
287+ ///
288+ /// # Returns
289+ ///
290+ /// The wire representing the updated array after the set operation.
291+ fn add_array_set (
292+ & mut self ,
293+ elem_ty : Type ,
294+ size : u64 ,
295+ input : Wire ,
296+ index : Wire ,
297+ value : Wire ,
298+ ) -> Result < Wire , BuildError > {
299+ self . add_generic_array_set :: < Array > ( elem_ty, size, input, index, value)
300+ }
301+
302+ /// Adds an array swap operation to the dataflow graph.
303+ ///
304+ /// This operation swaps the values at two specified indices in the array.
305+ ///
306+ /// # Arguments
307+ ///
308+ /// * `elem_ty` - The type of the elements in the array.
309+ /// * `size` - The size of the array.
310+ /// * `input` - The wire representing the array.
311+ /// * `index1` - The wire representing the first index to swap.
312+ /// * `index2` - The wire representing the second index to swap.
313+ ///
314+ /// # Errors
315+ ///
316+ /// Returns an error if building the operation fails.
317+ ///
318+ /// # Returns
319+ ///
320+ /// The wire representing the updated array after the swap operation.
321+ fn add_array_swap (
322+ & mut self ,
323+ elem_ty : Type ,
324+ size : u64 ,
325+ input : Wire ,
326+ index1 : Wire ,
327+ index2 : Wire ,
328+ ) -> Result < Wire , BuildError > {
329+ let op = GenericArrayOpDef :: < Array > :: swap. instantiate ( & [ size. into ( ) , elem_ty. into ( ) ] ) ?;
330+ let [ out] = self
331+ . add_dataflow_op ( op, vec ! [ input, index1, index2] ) ?
332+ . outputs_arr ( ) ;
333+ Ok ( out)
334+ }
335+
336+ /// Adds an array pop-left operation to the dataflow graph.
337+ ///
338+ /// This operation removes the leftmost element from the array.
339+ ///
340+ /// # Arguments
341+ ///
342+ /// * `elem_ty` - The type of the elements in the array.
343+ /// * `size` - The size of the array.
344+ /// * `input` - The wire representing the array.
345+ ///
346+ /// # Errors
347+ ///
348+ /// Returns an error if building the operation fails.
349+ ///
350+ /// # Returns
351+ ///
352+ /// The wire representing the Option<elemty, array<SIZE-1, elemty>>
353+ fn add_array_pop_left (
354+ & mut self ,
355+ elem_ty : Type ,
356+ size : u64 ,
357+ input : Wire ,
358+ ) -> Result < Wire , BuildError > {
359+ self . add_generic_array_pop_left :: < Array > ( elem_ty, size, input)
360+ }
361+
362+ /// Adds an array pop-right operation to the dataflow graph.
363+ ///
364+ /// This operation removes the rightmost element from the array.
365+ ///
366+ /// # Arguments
367+ ///
368+ /// * `elem_ty` - The type of the elements in the array.
369+ /// * `size` - The size of the array.
370+ /// * `input` - The wire representing the array.
371+ ///
372+ /// # Errors
373+ ///
374+ /// Returns an error if building the operation fails.
375+ ///
376+ /// # Returns
377+ ///
378+ /// The wire representing the Option<elemty, array<SIZE-1, elemty>>
379+ fn add_array_pop_right (
380+ & mut self ,
381+ elem_ty : Type ,
382+ size : u64 ,
383+ input : Wire ,
384+ ) -> Result < Wire , BuildError > {
385+ self . add_generic_array_pop_right :: < Array > ( elem_ty, size, input)
386+ }
387+
388+ /// Adds an operation to discard an empty array from the dataflow graph.
389+ ///
390+ /// # Arguments
391+ ///
392+ /// * `elem_ty` - The type of the elements in the array.
393+ /// * `input` - The wire representing the array.
394+ ///
395+ /// # Errors
396+ ///
397+ /// Returns an error if building the operation fails.
398+ fn add_array_discard_empty ( & mut self , elem_ty : Type , input : Wire ) -> Result < ( ) , BuildError > {
399+ self . add_generic_array_discard_empty :: < Array > ( elem_ty, input)
400+ }
401+ }
402+
403+ impl < D : Dataflow > ArrayOpBuilder for D { }
404+
173405#[ cfg( test) ]
174406mod test {
175407 use crate :: builder:: { inout_sig, DFGBuilder , Dataflow , DataflowHugr } ;
0 commit comments