Skip to main content

singe_npp/signal/
arithmetic.rs

1use singe_cuda::types::{Complex32, Complex64};
2use singe_npp_sys as sys;
3
4use crate::{
5    context::StreamContext,
6    error::Result,
7    signal::view::{SignalView, SignalViewMut},
8    try_ffi,
9    types::{ComplexI16, ComplexI32, DataTypeLike, IntoNpp, RoundMode},
10    utility::{to_u64, validate_same_len},
11};
12
13#[macro_use]
14#[path = "arithmetic_macros.rs"]
15mod arithmetic_macros;
16
17#[path = "arithmetic_constant_ops.rs"]
18mod constant_ops;
19pub use constant_ops::*;
20
21#[path = "arithmetic_binary_ops.rs"]
22mod binary_ops;
23pub use binary_ops::*;
24
25#[path = "arithmetic_unary_ops.rs"]
26#[macro_use]
27mod unary_ops;
28pub use unary_ops::*;
29
30macro_rules! impl_signal_constant_dispatch {
31    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
32        pub trait $trait: DataTypeLike {
33            fn $method(
34                stream_context: &StreamContext,
35                source: &SignalView<'_, Self>,
36                value: Self,
37                destination: &mut SignalViewMut<'_, Self>,
38            ) -> Result<()>;
39        }
40
41        $(
42            impl $trait for $ty {
43                fn $method(
44                    stream_context: &StreamContext,
45                    source: &SignalView<'_, Self>,
46                    value: Self,
47                    destination: &mut SignalViewMut<'_, Self>,
48                ) -> Result<()> {
49                    $direct(stream_context, source, value, destination)
50                }
51            }
52        )*
53
54        pub fn $function<T: $trait>(
55            stream_context: &StreamContext,
56            source: &SignalView<'_, T>,
57            value: T,
58            destination: &mut SignalViewMut<'_, T>,
59        ) -> Result<()> {
60            T::$method(stream_context, source, value, destination)
61        }
62    };
63}
64
65macro_rules! impl_signal_constant_in_place_dispatch {
66    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
67        pub trait $trait: DataTypeLike {
68            fn $method(
69                stream_context: &StreamContext,
70                signal: &mut SignalViewMut<'_, Self>,
71                value: Self,
72            ) -> Result<()>;
73        }
74
75        $(
76            impl $trait for $ty {
77                fn $method(
78                    stream_context: &StreamContext,
79                    signal: &mut SignalViewMut<'_, Self>,
80                    value: Self,
81                ) -> Result<()> {
82                    $direct(stream_context, signal, value)
83                }
84            }
85        )*
86
87        pub fn $function<T: $trait>(
88            stream_context: &StreamContext,
89            signal: &mut SignalViewMut<'_, T>,
90            value: T,
91        ) -> Result<()> {
92            T::$method(stream_context, signal, value)
93        }
94    };
95}
96
97macro_rules! impl_signal_scaled_constant_dispatch {
98    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
99        pub trait $trait: DataTypeLike {
100            fn $method(
101                stream_context: &StreamContext,
102                source: &SignalView<'_, Self>,
103                value: Self,
104                destination: &mut SignalViewMut<'_, Self>,
105                scale_factor: i32,
106            ) -> Result<()>;
107        }
108
109        $(
110            impl $trait for $ty {
111                fn $method(
112                    stream_context: &StreamContext,
113                    source: &SignalView<'_, Self>,
114                    value: Self,
115                    destination: &mut SignalViewMut<'_, Self>,
116                    scale_factor: i32,
117                ) -> Result<()> {
118                    $direct(stream_context, source, value, destination, scale_factor)
119                }
120            }
121        )*
122
123        pub fn $function<T: $trait>(
124            stream_context: &StreamContext,
125            source: &SignalView<'_, T>,
126            value: T,
127            destination: &mut SignalViewMut<'_, T>,
128            scale_factor: i32,
129        ) -> Result<()> {
130            T::$method(stream_context, source, value, destination, scale_factor)
131        }
132    };
133}
134
135macro_rules! impl_signal_scaled_constant_in_place_dispatch {
136    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
137        pub trait $trait: DataTypeLike {
138            fn $method(
139                stream_context: &StreamContext,
140                signal: &mut SignalViewMut<'_, Self>,
141                value: Self,
142                scale_factor: i32,
143            ) -> Result<()>;
144        }
145
146        $(
147            impl $trait for $ty {
148                fn $method(
149                    stream_context: &StreamContext,
150                    signal: &mut SignalViewMut<'_, Self>,
151                    value: Self,
152                    scale_factor: i32,
153                ) -> Result<()> {
154                    $direct(stream_context, signal, value, scale_factor)
155                }
156            }
157        )*
158
159        pub fn $function<T: $trait>(
160            stream_context: &StreamContext,
161            signal: &mut SignalViewMut<'_, T>,
162            value: T,
163            scale_factor: i32,
164        ) -> Result<()> {
165            T::$method(stream_context, signal, value, scale_factor)
166        }
167    };
168}
169
170impl_signal_constant_dispatch!(AddConstant, add_constant, add_constant, [
171    f32 => add_constant_f32,
172    f64 => add_constant_f64,
173    Complex32 => add_constant_f32_complex,
174    Complex64 => add_constant_f64_complex
175]);
176impl_signal_constant_dispatch!(SubtractConstant, subtract_constant, subtract_constant, [
177    f32 => subtract_constant_f32,
178    f64 => subtract_constant_f64,
179    Complex32 => subtract_constant_f32_complex,
180    Complex64 => subtract_constant_f64_complex
181]);
182impl_signal_constant_dispatch!(SubtractFromConstant, subtract_from_constant, subtract_from_constant, [
183    f32 => subtract_from_constant_f32,
184    f64 => subtract_from_constant_f64,
185    Complex32 => subtract_from_constant_f32_complex,
186    Complex64 => subtract_from_constant_f64_complex
187]);
188impl_signal_constant_dispatch!(MultiplyConstant, multiply_constant, multiply_constant, [
189    f32 => multiply_constant_f32,
190    f64 => multiply_constant_f64,
191    Complex32 => multiply_constant_f32_complex,
192    Complex64 => multiply_constant_f64_complex
193]);
194impl_signal_constant_dispatch!(DivideConstant, divide_constant, divide_constant, [
195    f32 => divide_constant_f32,
196    f64 => divide_constant_f64,
197    Complex32 => divide_constant_f32_complex,
198    Complex64 => divide_constant_f64_complex
199]);
200impl_signal_constant_dispatch!(DivideIntoConstant, divide_into_constant, divide_into_constant, [
201    u16 => divide_into_constant_u16,
202    f32 => divide_into_constant_f32
203]);
204impl_signal_constant_dispatch!(AndConstant, and_constant, and_constant, [
205    u8 => and_constant_u8,
206    u16 => and_constant_u16,
207    u32 => and_constant_u32
208]);
209impl_signal_constant_dispatch!(OrConstant, or_constant, or_constant, [
210    u8 => or_constant_u8,
211    u16 => or_constant_u16,
212    u32 => or_constant_u32
213]);
214impl_signal_constant_dispatch!(XorConstant, xor_constant, xor_constant, [
215    u8 => xor_constant_u8,
216    u16 => xor_constant_u16,
217    u32 => xor_constant_u32
218]);
219
220impl_signal_constant_in_place_dispatch!(AddConstantInPlace, add_constant_in_place, add_constant_in_place, [
221    f32 => add_constant_f32_in_place,
222    f64 => add_constant_f64_in_place,
223    Complex32 => add_constant_f32_complex_in_place,
224    Complex64 => add_constant_f64_complex_in_place
225]);
226impl_signal_constant_in_place_dispatch!(SubtractConstantInPlace, subtract_constant_in_place, subtract_constant_in_place, [
227    f32 => subtract_constant_f32_in_place,
228    f64 => subtract_constant_f64_in_place,
229    Complex32 => subtract_constant_f32_complex_in_place,
230    Complex64 => subtract_constant_f64_complex_in_place
231]);
232impl_signal_constant_in_place_dispatch!(SubtractFromConstantInPlace, subtract_from_constant_in_place, subtract_from_constant_in_place, [
233    f32 => subtract_from_constant_f32_in_place,
234    f64 => subtract_from_constant_f64_in_place,
235    Complex32 => subtract_from_constant_f32_complex_in_place,
236    Complex64 => subtract_from_constant_f64_complex_in_place
237]);
238impl_signal_constant_in_place_dispatch!(MultiplyConstantInPlace, multiply_constant_in_place, multiply_constant_in_place, [
239    f32 => multiply_constant_f32_in_place,
240    f64 => multiply_constant_f64_in_place,
241    Complex32 => multiply_constant_f32_complex_in_place,
242    Complex64 => multiply_constant_f64_complex_in_place
243]);
244impl_signal_constant_in_place_dispatch!(DivideConstantInPlace, divide_constant_in_place, divide_constant_in_place, [
245    f32 => divide_constant_f32_in_place,
246    f64 => divide_constant_f64_in_place,
247    Complex32 => divide_constant_f32_complex_in_place,
248    Complex64 => divide_constant_f64_complex_in_place
249]);
250impl_signal_constant_in_place_dispatch!(DivideIntoConstantInPlace, divide_into_constant_in_place, divide_into_constant_in_place, [
251    u16 => divide_into_constant_u16_in_place,
252    f32 => divide_into_constant_f32_in_place
253]);
254impl_signal_constant_in_place_dispatch!(AndConstantInPlace, and_constant_in_place, and_constant_in_place, [
255    u8 => and_constant_u8_in_place,
256    u16 => and_constant_u16_in_place,
257    u32 => and_constant_u32_in_place
258]);
259impl_signal_constant_in_place_dispatch!(OrConstantInPlace, or_constant_in_place, or_constant_in_place, [
260    u8 => or_constant_u8_in_place,
261    u16 => or_constant_u16_in_place,
262    u32 => or_constant_u32_in_place
263]);
264impl_signal_constant_in_place_dispatch!(XorConstantInPlace, xor_constant_in_place, xor_constant_in_place, [
265    u8 => xor_constant_u8_in_place,
266    u16 => xor_constant_u16_in_place,
267    u32 => xor_constant_u32_in_place
268]);
269
270impl_signal_scaled_constant_dispatch!(AddConstantScaled, add_constant_scaled, add_constant_scaled, [
271    u8 => add_constant_u8_scaled,
272    u16 => add_constant_u16_scaled,
273    i16 => add_constant_i16_scaled,
274    i32 => add_constant_i32_scaled,
275    ComplexI16 => add_constant_i16_complex_scaled,
276    ComplexI32 => add_constant_i32_complex_scaled
277]);
278impl_signal_scaled_constant_dispatch!(SubtractConstantScaled, subtract_constant_scaled, subtract_constant_scaled, [
279    u8 => subtract_constant_u8_scaled,
280    u16 => subtract_constant_u16_scaled,
281    i16 => subtract_constant_i16_scaled,
282    i32 => subtract_constant_i32_scaled,
283    ComplexI16 => subtract_constant_i16_complex_scaled,
284    ComplexI32 => subtract_constant_i32_complex_scaled
285]);
286impl_signal_scaled_constant_dispatch!(SubtractFromConstantScaled, subtract_from_constant_scaled, subtract_from_constant_scaled, [
287    u8 => subtract_from_constant_u8_scaled,
288    u16 => subtract_from_constant_u16_scaled,
289    i16 => subtract_from_constant_i16_scaled,
290    i32 => subtract_from_constant_i32_scaled,
291    ComplexI16 => subtract_from_constant_i16_complex_scaled,
292    ComplexI32 => subtract_from_constant_i32_complex_scaled
293]);
294impl_signal_scaled_constant_dispatch!(MultiplyConstantScaled, multiply_constant_scaled, multiply_constant_scaled, [
295    u8 => multiply_constant_u8_scaled,
296    u16 => multiply_constant_u16_scaled,
297    i16 => multiply_constant_i16_scaled,
298    i32 => multiply_constant_i32_scaled,
299    ComplexI16 => multiply_constant_i16_complex_scaled,
300    ComplexI32 => multiply_constant_i32_complex_scaled
301]);
302impl_signal_scaled_constant_dispatch!(DivideConstantScaled, divide_constant_scaled, divide_constant_scaled, [
303    u8 => divide_constant_u8_scaled,
304    u16 => divide_constant_u16_scaled,
305    i16 => divide_constant_i16_scaled,
306    ComplexI16 => divide_constant_i16_complex_scaled
307]);
308
309impl_signal_scaled_constant_in_place_dispatch!(AddConstantScaledInPlace, add_constant_scaled_in_place, add_constant_scaled_in_place, [
310    u8 => add_constant_u8_scaled_in_place,
311    u16 => add_constant_u16_scaled_in_place,
312    i16 => add_constant_i16_scaled_in_place,
313    i32 => add_constant_i32_scaled_in_place,
314    ComplexI16 => add_constant_i16_complex_scaled_in_place,
315    ComplexI32 => add_constant_i32_complex_scaled_in_place
316]);
317impl_signal_scaled_constant_in_place_dispatch!(SubtractConstantScaledInPlace, subtract_constant_scaled_in_place, subtract_constant_scaled_in_place, [
318    u8 => subtract_constant_u8_scaled_in_place,
319    u16 => subtract_constant_u16_scaled_in_place,
320    i16 => subtract_constant_i16_scaled_in_place,
321    i32 => subtract_constant_i32_scaled_in_place,
322    ComplexI16 => subtract_constant_i16_complex_scaled_in_place,
323    ComplexI32 => subtract_constant_i32_complex_scaled_in_place
324]);
325impl_signal_scaled_constant_in_place_dispatch!(SubtractFromConstantScaledInPlace, subtract_from_constant_scaled_in_place, subtract_from_constant_scaled_in_place, [
326    u8 => subtract_from_constant_u8_scaled_in_place,
327    u16 => subtract_from_constant_u16_scaled_in_place,
328    i16 => subtract_from_constant_i16_scaled_in_place,
329    i32 => subtract_from_constant_i32_scaled_in_place,
330    ComplexI16 => subtract_from_constant_i16_complex_scaled_in_place,
331    ComplexI32 => subtract_from_constant_i32_complex_scaled_in_place
332]);
333impl_signal_scaled_constant_in_place_dispatch!(MultiplyConstantScaledInPlace, multiply_constant_scaled_in_place, multiply_constant_scaled_in_place, [
334    u8 => multiply_constant_u8_scaled_in_place,
335    u16 => multiply_constant_u16_scaled_in_place,
336    i16 => multiply_constant_i16_scaled_in_place,
337    i32 => multiply_constant_i32_scaled_in_place,
338    ComplexI16 => multiply_constant_i16_complex_scaled_in_place,
339    ComplexI32 => multiply_constant_i32_complex_scaled_in_place
340]);
341impl_signal_scaled_constant_in_place_dispatch!(DivideConstantScaledInPlace, divide_constant_scaled_in_place, divide_constant_scaled_in_place, [
342    u8 => divide_constant_u8_scaled_in_place,
343    u16 => divide_constant_u16_scaled_in_place,
344    i16 => divide_constant_i16_scaled_in_place,
345    ComplexI16 => divide_constant_i16_complex_scaled_in_place
346]);
347
348macro_rules! impl_signal_destination_update_constant_dispatch {
349    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
350        pub trait $trait: DataTypeLike {
351            fn $method(
352                stream_context: &StreamContext,
353                source: &SignalView<'_, Self>,
354                value: Self,
355                destination: &mut SignalViewMut<'_, Self>,
356            ) -> Result<()>;
357        }
358
359        $(
360            impl $trait for $ty {
361                fn $method(
362                    stream_context: &StreamContext,
363                    source: &SignalView<'_, Self>,
364                    value: Self,
365                    destination: &mut SignalViewMut<'_, Self>,
366                ) -> Result<()> {
367                    $direct(stream_context, source, value, destination)
368                }
369            }
370        )*
371
372        pub fn $function<T: $trait>(
373            stream_context: &StreamContext,
374            source: &SignalView<'_, T>,
375            value: T,
376            destination: &mut SignalViewMut<'_, T>,
377        ) -> Result<()> {
378            T::$method(stream_context, source, value, destination)
379        }
380    };
381}
382
383macro_rules! impl_signal_mixed_constant_dispatch {
384    ($trait:ident, $method:ident, $function:ident, [$($source_ty:ty => ($destination_ty:ty, $direct:ident)),* $(,)?]) => {
385        pub trait $trait<Destination>: DataTypeLike
386        where
387            Destination: DataTypeLike,
388        {
389            fn $method(
390                stream_context: &StreamContext,
391                source: &SignalView<'_, Self>,
392                value: Self,
393                destination: &mut SignalViewMut<'_, Destination>,
394            ) -> Result<()>;
395        }
396
397        $(
398            impl $trait<$destination_ty> for $source_ty {
399                fn $method(
400                    stream_context: &StreamContext,
401                    source: &SignalView<'_, Self>,
402                    value: Self,
403                    destination: &mut SignalViewMut<'_, $destination_ty>,
404                ) -> Result<()> {
405                    $direct(stream_context, source, value, destination)
406                }
407            }
408        )*
409
410        pub fn $function<Source, Destination>(
411            stream_context: &StreamContext,
412            source: &SignalView<'_, Source>,
413            value: Source,
414            destination: &mut SignalViewMut<'_, Destination>,
415        ) -> Result<()>
416        where
417            Source: $trait<Destination>,
418            Destination: DataTypeLike,
419        {
420            Source::$method(stream_context, source, value, destination)
421        }
422    };
423}
424
425macro_rules! impl_signal_scaled_mixed_constant_dispatch {
426    ($trait:ident, $method:ident, $function:ident, [$($source_ty:ty => ($destination_ty:ty, $direct:ident)),* $(,)?]) => {
427        pub trait $trait<Destination>: DataTypeLike
428        where
429            Destination: DataTypeLike,
430        {
431            fn $method(
432                stream_context: &StreamContext,
433                source: &SignalView<'_, Self>,
434                value: Self,
435                destination: &mut SignalViewMut<'_, Destination>,
436                scale_factor: i32,
437            ) -> Result<()>;
438        }
439
440        $(
441            impl $trait<$destination_ty> for $source_ty {
442                fn $method(
443                    stream_context: &StreamContext,
444                    source: &SignalView<'_, Self>,
445                    value: Self,
446                    destination: &mut SignalViewMut<'_, $destination_ty>,
447                    scale_factor: i32,
448                ) -> Result<()> {
449                    $direct(stream_context, source, value, destination, scale_factor)
450                }
451            }
452        )*
453
454        pub fn $function<Source, Destination>(
455            stream_context: &StreamContext,
456            source: &SignalView<'_, Source>,
457            value: Source,
458            destination: &mut SignalViewMut<'_, Destination>,
459            scale_factor: i32,
460        ) -> Result<()>
461        where
462            Source: $trait<Destination>,
463            Destination: DataTypeLike,
464        {
465            Source::$method(stream_context, source, value, destination, scale_factor)
466        }
467    };
468}
469
470macro_rules! impl_signal_scaled_mixed_constant_in_place_dispatch {
471    ($trait:ident, $method:ident, $function:ident, [$($signal_ty:ty => ($value_ty:ty, $direct:ident)),* $(,)?]) => {
472        pub trait $trait<Value>: DataTypeLike
473        where
474            Value: DataTypeLike,
475        {
476            fn $method(
477                stream_context: &StreamContext,
478                signal: &mut SignalViewMut<'_, Self>,
479                value: Value,
480                scale_factor: i32,
481            ) -> Result<()>;
482        }
483
484        $(
485            impl $trait<$value_ty> for $signal_ty {
486                fn $method(
487                    stream_context: &StreamContext,
488                    signal: &mut SignalViewMut<'_, Self>,
489                    value: $value_ty,
490                    scale_factor: i32,
491                ) -> Result<()> {
492                    $direct(stream_context, signal, value, scale_factor)
493                }
494            }
495        )*
496
497        pub fn $function<Signal, Value>(
498            stream_context: &StreamContext,
499            signal: &mut SignalViewMut<'_, Signal>,
500            value: Value,
501            scale_factor: i32,
502        ) -> Result<()>
503        where
504            Signal: $trait<Value>,
505            Value: DataTypeLike,
506        {
507            Signal::$method(stream_context, signal, value, scale_factor)
508        }
509    };
510}
511
512impl_signal_destination_update_constant_dispatch!(AddProductConstant, add_product_constant, add_product_constant, [
513    f32 => add_product_constant_f32
514]);
515impl_signal_mixed_constant_dispatch!(MultiplyConstantLowTo, multiply_constant_low_to, multiply_constant_low_to, [
516    f32 => (i16, multiply_constant_f32_to_i16_low)
517]);
518impl_signal_scaled_mixed_constant_dispatch!(MultiplyConstantScaledTo, multiply_constant_scaled_to, multiply_constant_scaled_to, [
519    f32 => (i16, multiply_constant_f32_to_i16_scaled)
520]);
521impl_signal_scaled_mixed_constant_in_place_dispatch!(MultiplyConstantScaledToInPlace, multiply_constant_scaled_to_in_place, multiply_constant_scaled_to_in_place, [
522    i64 => (f64, multiply_constant_f64_to_i64_scaled_in_place)
523]);
524
525macro_rules! impl_signal_shift_constant_dispatch {
526    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
527        pub trait $trait: DataTypeLike {
528            fn $method(
529                stream_context: &StreamContext,
530                source: &SignalView<'_, Self>,
531                shift: i32,
532                destination: &mut SignalViewMut<'_, Self>,
533            ) -> Result<()>;
534        }
535
536        $(
537            impl $trait for $ty {
538                fn $method(
539                    stream_context: &StreamContext,
540                    source: &SignalView<'_, Self>,
541                    shift: i32,
542                    destination: &mut SignalViewMut<'_, Self>,
543                ) -> Result<()> {
544                    $direct(stream_context, source, shift, destination)
545                }
546            }
547        )*
548
549        pub fn $function<T: $trait>(
550            stream_context: &StreamContext,
551            source: &SignalView<'_, T>,
552            shift: i32,
553            destination: &mut SignalViewMut<'_, T>,
554        ) -> Result<()> {
555            T::$method(stream_context, source, shift, destination)
556        }
557    };
558}
559
560macro_rules! impl_signal_shift_constant_in_place_dispatch {
561    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
562        pub trait $trait: DataTypeLike {
563            fn $method(
564                stream_context: &StreamContext,
565                signal: &mut SignalViewMut<'_, Self>,
566                shift: i32,
567            ) -> Result<()>;
568        }
569
570        $(
571            impl $trait for $ty {
572                fn $method(
573                    stream_context: &StreamContext,
574                    signal: &mut SignalViewMut<'_, Self>,
575                    shift: i32,
576                ) -> Result<()> {
577                    $direct(stream_context, signal, shift)
578                }
579            }
580        )*
581
582        pub fn $function<T: $trait>(
583            stream_context: &StreamContext,
584            signal: &mut SignalViewMut<'_, T>,
585            shift: i32,
586        ) -> Result<()> {
587            T::$method(stream_context, signal, shift)
588        }
589    };
590}
591
592impl_signal_shift_constant_dispatch!(LeftShiftConstant, left_shift_constant, left_shift_constant, [
593    u8 => left_shift_constant_u8,
594    u16 => left_shift_constant_u16,
595    i16 => left_shift_constant_i16,
596    u32 => left_shift_constant_u32,
597    i32 => left_shift_constant_i32
598]);
599impl_signal_shift_constant_dispatch!(RightShiftConstant, right_shift_constant, right_shift_constant, [
600    u8 => right_shift_constant_u8,
601    u16 => right_shift_constant_u16,
602    i16 => right_shift_constant_i16,
603    u32 => right_shift_constant_u32,
604    i32 => right_shift_constant_i32
605]);
606impl_signal_shift_constant_in_place_dispatch!(LeftShiftConstantInPlace, left_shift_constant_in_place, left_shift_constant_in_place, [
607    u8 => left_shift_constant_u8_in_place,
608    u16 => left_shift_constant_u16_in_place,
609    i16 => left_shift_constant_i16_in_place,
610    u32 => left_shift_constant_u32_in_place,
611    i32 => left_shift_constant_i32_in_place
612]);
613impl_signal_shift_constant_in_place_dispatch!(RightShiftConstantInPlace, right_shift_constant_in_place, right_shift_constant_in_place, [
614    u8 => right_shift_constant_u8_in_place,
615    u16 => right_shift_constant_u16_in_place,
616    i16 => right_shift_constant_i16_in_place,
617    u32 => right_shift_constant_u32_in_place,
618    i32 => right_shift_constant_i32_in_place
619]);
620
621macro_rules! impl_signal_to_dispatch {
622    ($trait:ident, $method:ident, $function:ident, [$($source_ty:ty => ($destination_ty:ty, $direct:ident)),* $(,)?]) => {
623        pub trait $trait<Destination>: DataTypeLike
624        where
625            Destination: DataTypeLike,
626        {
627            fn $method(
628                stream_context: &StreamContext,
629                source: &SignalView<'_, Self>,
630                destination: &mut SignalViewMut<'_, Destination>,
631            ) -> Result<()>;
632        }
633
634        $(
635            impl $trait<$destination_ty> for $source_ty {
636                fn $method(
637                    stream_context: &StreamContext,
638                    source: &SignalView<'_, Self>,
639                    destination: &mut SignalViewMut<'_, $destination_ty>,
640                ) -> Result<()> {
641                    $direct(stream_context, source, destination)
642                }
643            }
644        )*
645
646        pub fn $function<Source, Destination>(
647            stream_context: &StreamContext,
648            source: &SignalView<'_, Source>,
649            destination: &mut SignalViewMut<'_, Destination>,
650        ) -> Result<()>
651        where
652            Source: $trait<Destination>,
653            Destination: DataTypeLike,
654        {
655            Source::$method(stream_context, source, destination)
656        }
657    };
658}
659
660macro_rules! impl_signal_scaled_to_dispatch {
661    ($trait:ident, $method:ident, $function:ident, [$($source_ty:ty => ($destination_ty:ty, $direct:ident)),* $(,)?]) => {
662        pub trait $trait<Destination>: DataTypeLike
663        where
664            Destination: DataTypeLike,
665        {
666            fn $method(
667                stream_context: &StreamContext,
668                source: &SignalView<'_, Self>,
669                destination: &mut SignalViewMut<'_, Destination>,
670                scale_factor: i32,
671            ) -> Result<()>;
672        }
673
674        $(
675            impl $trait<$destination_ty> for $source_ty {
676                fn $method(
677                    stream_context: &StreamContext,
678                    source: &SignalView<'_, Self>,
679                    destination: &mut SignalViewMut<'_, $destination_ty>,
680                    scale_factor: i32,
681                ) -> Result<()> {
682                    $direct(stream_context, source, destination, scale_factor)
683                }
684            }
685        )*
686
687        pub fn $function<Source, Destination>(
688            stream_context: &StreamContext,
689            source: &SignalView<'_, Source>,
690            destination: &mut SignalViewMut<'_, Destination>,
691            scale_factor: i32,
692        ) -> Result<()>
693        where
694            Source: $trait<Destination>,
695            Destination: DataTypeLike,
696        {
697            Source::$method(stream_context, source, destination, scale_factor)
698        }
699    };
700}
701
702impl_signal_to_dispatch!(ExponentTo, exponent_to, exponent_to, [
703    f32 => (f64, exponent_f32_to_f64)
704]);
705impl_signal_to_dispatch!(NaturalLogarithmTo, natural_logarithm_to, natural_logarithm_to, [
706    f64 => (f32, natural_logarithm_f64_to_f32)
707]);
708impl_signal_scaled_to_dispatch!(NaturalLogarithmScaledTo, natural_logarithm_scaled_to, natural_logarithm_scaled_to, [
709    i32 => (i16, natural_logarithm_i32_to_i16_scaled)
710]);
711impl_signal_scaled_to_dispatch!(CubeRootScaledTo, cube_root_scaled_to, cube_root_scaled_to, [
712    i32 => (i16, cube_root_i32_to_i16_scaled)
713]);
714impl_signal_scaled_to_dispatch!(SquareRootScaledTo, square_root_scaled_to, square_root_scaled_to, [
715    i32 => (i16, square_root_i32_to_i16_scaled),
716    i64 => (i16, square_root_i64_to_i16_scaled)
717]);
718
719impl_signal_unary_dispatch!(CubeRoot, cube_root, cube_root, [
720    f32 => cube_root_f32
721]);
722impl_signal_scaled_unary_dispatch!(TenTimesLog10Scaled, ten_times_log10_scaled, ten_times_log10_scaled, [
723    i32 => ten_times_log10_i32_scaled
724]);
725impl_signal_scaled_unary_in_place_dispatch!(TenTimesLog10ScaledInPlace, ten_times_log10_scaled_in_place, ten_times_log10_scaled_in_place, [
726    i32 => ten_times_log10_i32_scaled_in_place
727]);
728
729macro_rules! impl_signal_normalize_dispatch {
730    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => ($scale_ty:ty, $direct:ident)),* $(,)?]) => {
731        pub trait $trait: DataTypeLike {
732            type Scale: DataTypeLike;
733
734            fn $method(
735                stream_context: &StreamContext,
736                source: &SignalView<'_, Self>,
737                destination: &mut SignalViewMut<'_, Self>,
738                subtract: Self,
739                divide: Self::Scale,
740            ) -> Result<()>;
741        }
742
743        $(
744            impl $trait for $ty {
745                type Scale = $scale_ty;
746
747                fn $method(
748                    stream_context: &StreamContext,
749                    source: &SignalView<'_, Self>,
750                    destination: &mut SignalViewMut<'_, Self>,
751                    subtract: Self,
752                    divide: Self::Scale,
753                ) -> Result<()> {
754                    $direct(stream_context, source, destination, subtract, divide)
755                }
756            }
757        )*
758
759        pub fn $function<T: $trait>(
760            stream_context: &StreamContext,
761            source: &SignalView<'_, T>,
762            destination: &mut SignalViewMut<'_, T>,
763            subtract: T,
764            divide: T::Scale,
765        ) -> Result<()> {
766            T::$method(stream_context, source, destination, subtract, divide)
767        }
768    };
769}
770
771macro_rules! impl_signal_scaled_normalize_dispatch {
772    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => ($divisor_ty:ty, $direct:ident)),* $(,)?]) => {
773        pub trait $trait: DataTypeLike {
774            type Divisor: DataTypeLike;
775
776            fn $method(
777                stream_context: &StreamContext,
778                source: &SignalView<'_, Self>,
779                destination: &mut SignalViewMut<'_, Self>,
780                subtract: Self,
781                divide: Self::Divisor,
782                scale_factor: i32,
783            ) -> Result<()>;
784        }
785
786        $(
787            impl $trait for $ty {
788                type Divisor = $divisor_ty;
789
790                fn $method(
791                    stream_context: &StreamContext,
792                    source: &SignalView<'_, Self>,
793                    destination: &mut SignalViewMut<'_, Self>,
794                    subtract: Self,
795                    divide: Self::Divisor,
796                    scale_factor: i32,
797                ) -> Result<()> {
798                    $direct(stream_context, source, destination, subtract, divide, scale_factor)
799                }
800            }
801        )*
802
803        pub fn $function<T: $trait>(
804            stream_context: &StreamContext,
805            source: &SignalView<'_, T>,
806            destination: &mut SignalViewMut<'_, T>,
807            subtract: T,
808            divide: T::Divisor,
809            scale_factor: i32,
810        ) -> Result<()> {
811            T::$method(stream_context, source, destination, subtract, divide, scale_factor)
812        }
813    };
814}
815
816impl_signal_normalize_dispatch!(Normalize, normalize, normalize, [
817    f32 => (f32, normalize_f32),
818    f64 => (f64, normalize_f64),
819    Complex32 => (f32, normalize_f32_complex),
820    Complex64 => (f64, normalize_f64_complex)
821]);
822impl_signal_scaled_normalize_dispatch!(NormalizeScaled, normalize_scaled, normalize_scaled, [
823    i16 => (i32, normalize_i16_scaled),
824    ComplexI16 => (i32, normalize_i16_complex_scaled)
825]);
826
827macro_rules! impl_signal_parameterized_unary_in_place_dispatch {
828    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => ($parameter_ty:ty, $direct:ident)),* $(,)?]) => {
829        pub trait $trait: DataTypeLike {
830            type Parameter: DataTypeLike;
831
832            fn $method(
833                stream_context: &StreamContext,
834                signal: &mut SignalViewMut<'_, Self>,
835                parameter: Self::Parameter,
836            ) -> Result<()>;
837        }
838
839        $(
840            impl $trait for $ty {
841                type Parameter = $parameter_ty;
842
843                fn $method(
844                    stream_context: &StreamContext,
845                    signal: &mut SignalViewMut<'_, Self>,
846                    parameter: Self::Parameter,
847                ) -> Result<()> {
848                    $direct(stream_context, signal, parameter)
849                }
850            }
851        )*
852
853        pub fn $function<T: $trait>(
854            stream_context: &StreamContext,
855            signal: &mut SignalViewMut<'_, T>,
856            parameter: T::Parameter,
857        ) -> Result<()> {
858            T::$method(stream_context, signal, parameter)
859        }
860    };
861}
862
863impl_signal_parameterized_unary_in_place_dispatch!(CauchyInPlace, cauchy_in_place, cauchy_in_place, [
864    f32 => (f32, cauchy_f32_in_place)
865]);
866impl_signal_parameterized_unary_in_place_dispatch!(CauchyDerivativeInPlace, cauchy_derivative_in_place, cauchy_derivative_in_place, [
867    f32 => (f32, cauchy_derivative_f32_in_place)
868]);