std_mel/ops/
num.rs

1use melodium_core::*;
2use melodium_macro::{check, mel_function, mel_treatment};
3
4/// Return absolute value.
5///
6/// If the absolute value cannot fit into the type itself (such as `i8` `-128` that cannot be turned into `128`), none value is returned.
7#[mel_function(
8    generic N (Signed)
9)]
10pub fn abs(value: N) -> Option<N> {
11    value.signed_abs()
12}
13
14/// Give the absolute values of a stream.
15///
16/// If the absolute value cannot fit into the type itself (such as `i8` `-128` that cannot be turned into `128`), none value is returned.
17#[mel_treatment(
18    generic N (Signed)
19    input value Stream<N>
20    output abs Stream<Option<N>>
21)]
22pub async fn abs() {
23    while let Ok(values) = value
24        .recv_many()
25        .await
26        .map(|values| Into::<VecDeque<Value>>::into(values))
27    {
28        check!(
29            abs.send_many(TransmissionValue::Other(
30                values
31                    .into_iter()
32                    .map(|val| val.signed_abs().into())
33                    .collect()
34            ))
35            .await
36        )
37    }
38}
39
40/// Return number representing sign of given value.
41///
42/// - `0` if number is 0,
43/// - `-1` if number is negative,
44/// - `1` if number is positive.
45///
46/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `NaN` output, `+INFINITY` and `+0.0` gives `1`, `-INFINITY` and `-0.0` gives `-1`.
47#[mel_function(
48    generic N (Signed)
49)]
50pub fn signum(value: N) -> N {
51    value.signed_signum()
52}
53
54/// Gives numeric sign of a stream.
55///
56/// - `0` if number is 0,
57/// - `-1` if number is negative,
58/// - `1` if number is positive.
59///
60/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `NaN` output, `+INFINITY` and `+0.0` gives `1`, `-INFINITY` and `-0.0` gives `-1`.
61#[mel_treatment(
62    generic N (Signed)
63    input value Stream<N>
64    output sign Stream<N>
65)]
66pub async fn signum() {
67    while let Ok(values) = value
68        .recv_many()
69        .await
70        .map(|values| Into::<VecDeque<Value>>::into(values))
71    {
72        check!(
73            sign.send_many(TransmissionValue::Other(
74                values.into_iter().map(|val| val.signed_signum()).collect()
75            ))
76            .await
77        )
78    }
79}
80
81/// Tells if a value is positive.
82///
83/// Returns `true` for strictly positive integers, and `false` for `0` and negative ones.  
84/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `false`, `+INFINITY` and `+0.0` gives `true`.
85#[mel_function(
86    generic N (Signed)
87)]
88pub fn is_positive(value: N) -> bool {
89    value.signed_is_positive()
90}
91
92/// Tells if a stream contains positive values.
93///
94/// Output `true` for strictly positive integers, and `false` for `0` and negative ones.  
95/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `false`, `+INFINITY` and `+0.0` gives `true`.
96#[mel_treatment(
97    generic N (Signed)
98    input value Stream<N>
99    output positive Stream<bool>
100)]
101pub async fn is_positive() {
102    while let Ok(values) = value
103        .recv_many()
104        .await
105        .map(|values| Into::<VecDeque<Value>>::into(values))
106    {
107        check!(
108            positive
109                .send_many(TransmissionValue::Bool(
110                    values
111                        .into_iter()
112                        .map(|val| val.signed_is_positive().into())
113                        .collect()
114                ))
115                .await
116        )
117    }
118}
119
120/// Tells if a value is negative.
121///
122/// Returns `true` for strictly negative integers, and `false` for `0` and positive ones.  
123/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `false`, `-INFINITY` and `-0.0` gives `true`.
124#[mel_function(
125    generic N (Signed)
126)]
127pub fn is_negative(value: N) -> bool {
128    value.signed_is_negative()
129}
130
131/// Tells if a stream contains negative values.
132///
133/// Output `true` for strictly negative integers, and `false` for `0` and positive ones.  
134/// ℹ️ For floating types (`f32` and `f64`), `NaN` values gives `false`, `-INFINITY` and `-0.0` gives `true`.
135#[mel_treatment(
136    generic N (Signed)
137    input value Stream<N>
138    output negative Stream<bool>
139)]
140pub async fn is_negative() {
141    while let Ok(values) = value
142        .recv_many()
143        .await
144        .map(|values| Into::<VecDeque<Value>>::into(values))
145    {
146        check!(
147            negative
148                .send_many(TransmissionValue::Bool(
149                    values
150                        .into_iter()
151                        .map(|val| val.signed_is_negative().into())
152                        .collect()
153                ))
154                .await
155        )
156    }
157}
158
159/// Add `a` and `b`
160///
161/// This function is infaillible but may overflow if `a + b` is out of bounds for the data type.
162#[mel_function(
163    generic N (Add)
164)]
165pub fn add(a: N, b: N) -> N {
166    a.add(&b)
167}
168
169/// Add values from two streams.
170///
171/// Values passed through `a` & `b` are added and send in `sum`.
172/// This treatment is infaillible but output may overflow if `a + b` is out of bounds for the data type.
173#[mel_treatment(
174    generic N (Add)
175    input a Stream<N>
176    input b Stream<N>
177    output sum Stream<N>
178)]
179pub async fn add() {
180    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
181        check!(sum.send_one(a.add(&b)).await)
182    }
183}
184
185/// Add `a` and `b`, checking if overflow occurs
186///
187/// This function returns an option containing `a + b`, or none if result cause overflow in data type.
188#[mel_function(
189    generic N (CheckedAdd)
190)]
191pub fn checked_add(a: N, b: N) -> Option<N> {
192    a.checked_add(&b)
193}
194
195/// Add values from two streams, checking if overflow occurs.
196///
197/// Values passed through `a` & `b` are added and send in `sum`.
198/// This treatment outputs an option containing `a + b`, or none if result cause overflow in data type.
199#[mel_treatment(
200    generic N (CheckedAdd)
201    input a Stream<N>
202    input b Stream<N>
203    output sum Stream<Option<N>>
204)]
205pub async fn checked_add() {
206    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
207        check!(sum.send_one(a.checked_add(&b).into()).await)
208    }
209}
210
211/// Add `a` and `b`, saturating to bounds.
212///
213/// This function is infaillible and saturate to the closest bound, minimal or maximal, if `a + b` is out of bounds for the data type.
214#[mel_function(
215    generic N (SaturatingAdd)
216)]
217pub fn saturating_add(a: N, b: N) -> N {
218    a.saturating_add(&b)
219}
220
221/// Add values from two streams, saturating to bounds.
222///
223/// Values passed through `a` & `b` are added and send in `sum`.
224/// This treatment is infaillible and saturate to the closest bound, minimal or maximal, if `a + b` is out of bounds for the data type.
225#[mel_treatment(
226    generic N (SaturatingAdd)
227    input a Stream<N>
228    input b Stream<N>
229    output sum Stream<N>
230)]
231pub async fn saturating_add() {
232    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
233        check!(sum.send_one(a.saturating_add(&b)).await)
234    }
235}
236
237/// Add `a` and `b`, wrapping on bounds.
238///
239/// This function is infaillible and wrap if `a + b` reach boundary of the data type.
240#[mel_function(
241    generic N (WrappingAdd)
242)]
243pub fn wrapping_add(a: N, b: N) -> N {
244    a.wrapping_add(&b)
245}
246
247/// Add values from two streams, wrapping on bounds.
248///
249/// Values passed through `a` & `b` are added and send in `sum`.
250/// This treatment is infaillible and wrap if `a + b` reach boundary of the data type.
251#[mel_treatment(
252    generic N (WrappingAdd)
253    input a Stream<N>
254    input b Stream<N>
255    output sum Stream<N>
256)]
257pub async fn wrapping_add() {
258    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
259        check!(sum.send_one(a.wrapping_add(&b)).await)
260    }
261}
262
263/// Sustract `b` from `a`
264///
265/// This function is infaillible but may overflow if `a - b` is out of bounds for the data type.
266#[mel_function(
267    generic N (Sub)
268)]
269pub fn sub(a: N, b: N) -> N {
270    a.sub(&b)
271}
272
273/// Substract values from two streams.
274///
275/// Values passed through `b` are substracted to `a` and send in `diff`.
276/// This treatment is infaillible but output may overflow if `a - b` is out of bounds for the data type.
277#[mel_treatment(
278    generic N (Add)
279    input a Stream<N>
280    input b Stream<N>
281    output diff Stream<N>
282)]
283pub async fn sub() {
284    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
285        check!(diff.send_one(a.sub(&b)).await)
286    }
287}
288
289/// Sustract `b` from `a`, checking if overflow occurs
290///
291/// This function returns an option containing `a - b`, or none if result cause overflow in data type.
292#[mel_function(
293    generic N (CheckedSub)
294)]
295pub fn checked_sub(a: N, b: N) -> Option<N> {
296    a.checked_sub(&b)
297}
298
299/// Substract values from two streams, checking if overflow occurs.
300///
301/// Values passed through `b` are substracted to `a` and send in `diff`.
302/// This treatment outputs an option containing `a - b`, or none if result cause overflow in data type.
303#[mel_treatment(
304    generic N (CheckedSub)
305    input a Stream<N>
306    input b Stream<N>
307    output diff Stream<Option<N>>
308)]
309pub async fn checked_sub() {
310    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
311        check!(diff.send_one(a.checked_sub(&b).into()).await)
312    }
313}
314
315/// Sustract `b` from `a`, saturating to bounds.
316///
317/// This function is infaillible and saturate to the closest bound, minimal or maximal, if `a - b` is out of bounds for the data type.
318#[mel_function(
319    generic N (SaturatingSub)
320)]
321pub fn saturating_sub(a: N, b: N) -> N {
322    a.saturating_sub(&b)
323}
324
325/// Substract values from two streams, saturating to bounds.
326///
327/// Values passed through `b` are substracted to `a` and send in `diff`.
328/// This treatment is infaillible and saturate to the closest bound, minimal or maximal, if `a - b` is out of bounds for the data type.
329#[mel_treatment(
330    generic N (SaturatingSub)
331    input a Stream<N>
332    input b Stream<N>
333    output diff Stream<N>
334)]
335pub async fn saturating_sub() {
336    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
337        check!(diff.send_one(a.saturating_sub(&b)).await)
338    }
339}
340
341/// Sustract `b` from `a`, wrapping on bounds.
342///
343/// This function is infaillible and wrap if `a - b` reach boundary of the data type.
344#[mel_function(
345    generic N (WrappingSub)
346)]
347pub fn wrapping_sub(a: N, b: N) -> N {
348    a.wrapping_sub(&b)
349}
350
351/// Substract values from two streams, wrapping on bounds.
352///
353/// Values passed through `b` are substracted to `a` and send in `diff`.
354/// This treatment is infaillible and wrap if `a - b` reach boundary of the data type.
355#[mel_treatment(
356    generic N (WrappingSub)
357    input a Stream<N>
358    input b Stream<N>
359    output diff Stream<N>
360)]
361pub async fn wrapping_sub() {
362    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
363        check!(diff.send_one(a.wrapping_sub(&b)).await)
364    }
365}
366
367/// Multiply `a` and `b`
368///
369/// This function is infaillible but may overflow if `a × b` is out of bounds for the data type.
370#[mel_function(
371    generic N (Mul)
372)]
373pub fn mul(a: N, b: N) -> N {
374    a.mul(&b)
375}
376
377/// Multiply values from two streams.
378///
379/// Values passed through `a` & `b` are multiplied and send in `prod`.
380/// This treatment is infaillible but output may overflow if `a × b` is out of bounds for the data type.
381#[mel_treatment(
382    generic N (Mul)
383    input a Stream<N>
384    input b Stream<N>
385    output prod Stream<N>
386)]
387pub async fn mul() {
388    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
389        check!(prod.send_one(a.mul(&b)).await)
390    }
391}
392
393/// Multiply `a` and `b`, checking if overflow occurs
394///
395/// This function returns an option containing `a × b`, or none if result cause overflow in data type.
396#[mel_function(
397    generic N (CheckedMul)
398)]
399pub fn checked_mul(a: N, b: N) -> Option<N> {
400    a.checked_mul(&b)
401}
402
403/// Multiply values from two streams, checking if overflow occurs.
404///
405/// Values passed through `a` & `b` are multiplied and send in `prod`.
406/// This treatment outputs an option containing `a × b`, or none if result cause overflow in data type.
407#[mel_treatment(
408    generic N (CheckedMul)
409    input a Stream<N>
410    input b Stream<N>
411    output prod Stream<Option<N>>
412)]
413pub async fn checked_mul() {
414    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
415        check!(prod.send_one(a.checked_mul(&b).into()).await)
416    }
417}
418
419/// Multiply `a` and `b`, saturating to bounds.
420///
421/// This function is infaillible and saturate to the closest bound, minimal or maximal, if `a × b` is out of bounds for the data type.
422#[mel_function(
423    generic N (SaturatingMul)
424)]
425pub fn saturating_mul(a: N, b: N) -> N {
426    a.saturating_mul(&b)
427}
428
429/// Multiply values from two streams, saturating to bounds.
430///
431/// Values passed through `a` & `b` are multiplied and send in `prod`.
432/// This treatment is infaillible and saturate to the closest bound, minimal or maximal, if `a × b` is out of bounds for the data type.
433#[mel_treatment(
434    generic N (SaturatingMul)
435    input a Stream<N>
436    input b Stream<N>
437    output prod Stream<N>
438)]
439pub async fn saturating_mul() {
440    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
441        check!(prod.send_one(a.saturating_mul(&b)).await)
442    }
443}
444
445/// Multiply `a` and `b`, wrapping on bounds.
446///
447/// This function is infaillible and wrap if `a × b` reach boundary of the data type.
448#[mel_function(
449    generic N (WrappingMul)
450)]
451pub fn wrapping_mul(a: N, b: N) -> N {
452    a.wrapping_mul(&b)
453}
454
455/// Multiply values from two streams, wrapping on bounds.
456///
457/// Values passed through `a` & `b` are multiplied and send in `prod`.
458/// This treatment is infaillible and wrap if `a × b` reach boundary of the data type.
459#[mel_treatment(
460    generic N (WrappingMul)
461    input a Stream<N>
462    input b Stream<N>
463    output prod Stream<N>
464)]
465pub async fn wrapping_mul() {
466    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
467        check!(prod.send_one(a.wrapping_mul(&b)).await)
468    }
469}
470
471/// Divide `a` by `b`
472///
473/// This function is infaillible but may overflow if `a ÷ b` is out of bounds for the data type.  
474/// ⚠️ For integers, this function returns `0` for divisions by `0`.  
475/// ℹ️ For floating types, this function return infinity for divisions by `0`.
476#[mel_function(
477    generic N (Div)
478)]
479pub fn div(a: N, b: N) -> N {
480    a.div(&b)
481}
482
483/// Divide values from two streams.
484///
485/// Values passed through `a` are divided by `b` and send in `quot`.
486/// This treatment is infaillible but may overflow if `a ÷ b` is out of bounds for the data type.  
487/// ⚠️ For integers, this treatment outputs `0` for divisions by `0`.  
488/// ℹ️ For floating types, this treatment return infinity for divisions by `0`.
489#[mel_treatment(
490    generic N (Div)
491    input a Stream<N>
492    input b Stream<N>
493    output quot Stream<N>
494)]
495pub async fn div() {
496    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
497        check!(quot.send_one(a.div(&b)).await)
498    }
499}
500
501/// Divide `a` by `b`, checking if division is possible or if overflow occurs
502///
503/// This function returns an option containing `a ÷ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
504#[mel_function(
505    generic N (CheckedDiv)
506)]
507pub fn checked_div(a: N, b: N) -> Option<N> {
508    a.checked_div(&b)
509}
510
511/// Divide values from two streams, checking if division is possible or if overflow occurs.
512///
513/// Values passed through `a` are divided by `b` and send in `quot`.
514/// This treatment outputs an option containing `a ÷ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
515#[mel_treatment(
516    generic N (CheckedDiv)
517    input a Stream<N>
518    input b Stream<N>
519    output quot Stream<Option<N>>
520)]
521pub async fn checked_div() {
522    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
523        check!(quot.send_one(a.checked_div(&b).into()).await)
524    }
525}
526
527/// Gives remainder of `a` divided by `b`
528///
529/// This function is infaillible but may overflow if `a _mod_ b` is out of bounds for the data type.  
530/// ⚠️ For integers, this function returns `0` for divisions by `0`.  
531/// ℹ️ For floating types, this function return not-a-number (`NaN`) for divisions by `0`.
532#[mel_function(
533    generic N (Rem)
534)]
535pub fn rem(a: N, b: N) -> N {
536    a.rem(&b)
537}
538
539/// Gives remainder of division from two streams.
540///
541/// Remainder is computed for values passed through `a` divided by `b` and send in `rem`.
542/// This treatment is infaillible but may overflow if `a _mod_ b` is out of bounds for the data type.  
543/// ⚠️ For integers, this treatment outputs `0` for divisions by `0`.  
544/// ℹ️ For floating types, this treatment return not-a-number (`NaN`) for divisions by `0`.
545#[mel_treatment(
546    generic N (Rem)
547    input a Stream<N>
548    input b Stream<N>
549    output rem Stream<N>
550)]
551pub async fn rem() {
552    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
553        check!(rem.send_one(a.rem(&b)).await)
554    }
555}
556
557/// Gives remainder of `a` divided by `b`, checking if division is possible or if overflow occurs
558///
559/// This function returns an option containing `a _mod_ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
560#[mel_function(
561    generic N (CheckedRem)
562)]
563pub fn checked_rem(a: N, b: N) -> Option<N> {
564    a.checked_rem(&b)
565}
566
567/// Gives remainder of division from two streams, checking if division is possible or if overflow occurs.
568///
569/// Remainder is computed for values passed through `a` divided by `b` and send in `rem`.
570/// This treatment outputs an option containing `a _mod_ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
571#[mel_treatment(
572    generic N (CheckedRem)
573    input a Stream<N>
574    input b Stream<N>
575    output rem Stream<Option<N>>
576)]
577pub async fn checked_rem() {
578    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
579        check!(rem.send_one(a.checked_rem(&b).into()).await)
580    }
581}
582
583/// Return negation of given value
584///
585/// This function is infaillible but may overflow if `-val` is out of bounds for the data type.
586#[mel_function(
587    generic N (Neg)
588)]
589pub fn neg(val: N) -> N {
590    val.neg()
591}
592
593/// Give negation of streamed values
594///
595/// This treatment is infaillible but output may overflow if `-value` is out of bounds for the data type.
596#[mel_treatment(
597    generic N (Neg)
598    input value Stream<N>
599    output neg Stream<N>
600)]
601pub async fn neg() {
602    while let Ok(values) = value
603        .recv_many()
604        .await
605        .map(|values| Into::<VecDeque<Value>>::into(values))
606    {
607        check!(
608            neg.send_many(TransmissionValue::Other(
609                values.into_iter().map(|val| val.neg()).collect()
610            ))
611            .await
612        )
613    }
614}
615
616/// Return negation of given value, checking if overflow occurs
617///
618/// This function returns an option containing `-val`, or none if result cause overflow in data type.
619#[mel_function(
620    generic N (CheckedNeg)
621)]
622pub fn checked_neg(val: N) -> Option<N> {
623    val.checked_neg()
624}
625
626/// Give negation of streamed values, checking if overflow occurs.
627///
628/// This treatment outputs an option containing `-value`, or none if result cause overflow in data type.
629#[mel_treatment(
630    generic N (CheckedNeg)
631    input value Stream<N>
632    output neg Stream<Option<N>>
633)]
634pub async fn checked_neg() {
635    while let Ok(values) = value
636        .recv_many()
637        .await
638        .map(|values| Into::<VecDeque<Value>>::into(values))
639    {
640        check!(
641            neg.send_many(TransmissionValue::Other(
642                values
643                    .into_iter()
644                    .map(|val| val.checked_neg().into())
645                    .collect()
646            ))
647            .await
648        )
649    }
650}
651
652/// Return negation of given value, wrapping on bounds.
653///
654/// This function is infaillible and wrap if `-val` reach boundary of the data type.
655#[mel_function(
656    generic N (WrappingNeg)
657)]
658pub fn wrapping_neg(val: N) -> N {
659    val.wrapping_neg()
660}
661
662/// Give negation of streamed values, wrapping on bounds.
663///
664/// This treatment is infaillible and wrap if `-value` reach boundary of the data type.
665#[mel_treatment(
666    generic N (WrappingNeg)
667    input value Stream<N>
668    output neg Stream<N>
669)]
670pub async fn wrapping_neg() {
671    while let Ok(values) = value
672        .recv_many()
673        .await
674        .map(|values| Into::<VecDeque<Value>>::into(values))
675    {
676        check!(
677            neg.send_many(TransmissionValue::Other(
678                values
679                    .into_iter()
680                    .map(|val| val.wrapping_neg().into())
681                    .collect()
682            ))
683            .await
684        )
685    }
686}
687
688/// Compute exponent of given value
689///
690/// This function is infaillible but may overflow if `valᵉˣᵖ` is out of bounds for the data type.
691#[mel_function(
692    generic N (Pow)
693)]
694pub fn pow(val: N, exp: u32) -> N {
695    val.pow(&exp)
696}
697
698/// Compute exponent of streamed values
699///
700/// This treatment is infaillible but output may overflow if `valueᵉˣᵖ` is out of bounds for the data type.
701#[mel_treatment(
702    generic N (Pow)
703    input value Stream<N>
704    output pow Stream<N>
705)]
706pub async fn pow(exp: u32) {
707    while let Ok(values) = value
708        .recv_many()
709        .await
710        .map(|values| Into::<VecDeque<Value>>::into(values))
711    {
712        check!(
713            pow.send_many(TransmissionValue::Other(
714                values.into_iter().map(|val| val.pow(&exp)).collect()
715            ))
716            .await
717        )
718    }
719}
720
721/// Compute exponent of given value, checking if overflow occurs
722///
723/// This function returns an option containing `valᵉˣᵖ`, or none if result cause overflow in data type.
724#[mel_function(
725    generic N (CheckedPow)
726)]
727pub fn checked_pow(val: N, exp: u32) -> Option<N> {
728    val.checked_pow(&exp)
729}
730
731/// Compute exponent of streamed values, checking if overflow occurs.
732///
733/// This treatment outputs an option containing `valᵉˣᵖ`, or none if result cause overflow in data type.
734#[mel_treatment(
735    generic N (CheckedPow)
736    input value Stream<N>
737    output pow Stream<Option<N>>
738)]
739pub async fn checked_pow(exp: u32) {
740    while let Ok(values) = value
741        .recv_many()
742        .await
743        .map(|values| Into::<VecDeque<Value>>::into(values))
744    {
745        check!(
746            pow.send_many(TransmissionValue::Other(
747                values
748                    .into_iter()
749                    .map(|val| val.checked_pow(&exp).into())
750                    .collect()
751            ))
752            .await
753        )
754    }
755}
756
757/// Proceed to euclidian division of `a` by `b`
758///
759/// This function is infaillible but may overflow if `a ÷ b` is out of bounds for the data type.  
760/// ⚠️ For integers, this function returns `0` for divisions by `0`.  
761/// ℹ️ For floating types, this function return infinity for divisions by `0`.
762#[mel_function(
763    generic N (Euclid)
764)]
765pub fn euclid_div(a: N, b: N) -> N {
766    a.euclid_div(&b)
767}
768
769/// Proceed to euclidian division from two streams.
770///
771/// Values passed through `a` are divided by `b` and send in `quot`.
772/// This treatment is infaillible but may overflow if `a ÷ b` is out of bounds for the data type.  
773/// ⚠️ For integers, this treatment outputs `0` for divisions by `0`.  
774/// ℹ️ For floating types, this treatment return infinity for divisions by `0`.
775#[mel_treatment(
776    generic N (Euclid)
777    input a Stream<N>
778    input b Stream<N>
779    output quot Stream<N>
780)]
781pub async fn euclid_div() {
782    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
783        check!(quot.send_one(a.euclid_div(&b)).await)
784    }
785}
786
787/// Gives euclidian remainder of `a` divided by `b`
788///
789/// This function is infaillible but may overflow if `a _mod_ b` is out of bounds for the data type.  
790/// ⚠️ For integers, this function returns `0` for divisions by `0`.  
791/// ℹ️ For floating types, this function return not-a-number (`NaN`) for divisions by `0`.
792#[mel_function(
793    generic N (Euclid)
794)]
795pub fn euclid_rem(a: N, b: N) -> N {
796    a.euclid_rem(&b)
797}
798
799/// Gives euclidian remainder of division from two streams.
800///
801/// Remainder is computed for values passed through `a` divided by `b` and send in `rem`.
802/// This treatment is infaillible but may overflow if `a _mod_ b` is out of bounds for the data type.  
803/// ⚠️ For integers, this treatment outputs `0` for divisions by `0`.  
804/// ℹ️ For floating types, this treatment return not-a-number (`NaN`) for divisions by `0`.
805#[mel_treatment(
806    generic N (Euclid)
807    input a Stream<N>
808    input b Stream<N>
809    output rem Stream<N>
810)]
811pub async fn euclid_rem() {
812    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
813        check!(rem.send_one(a.euclid_rem(&b)).await)
814    }
815}
816
817/// Proceed to euclidian division of `a` by `b`, checking if division is possible or if overflow occurs
818///
819/// This function returns an option containing `a ÷ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
820/// ℹ️ For floating types, this function return infinity for divisions by `0`.
821#[mel_function(
822    generic N (CheckedEuclid)
823)]
824pub fn checked_euclid_div(a: N, b: N) -> Option<N> {
825    a.checked_euclid_div(&b)
826}
827
828/// Proceed to euclidian division from two streams, checking if division is possible or if overflow occurs.
829///
830/// Values passed through `a` are divided by `b` and send in `quot`.
831/// This treatment outputs an option containing `a ÷ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
832/// ℹ️ For floating types, this function return infinity for divisions by `0`.
833#[mel_treatment(
834    generic N (CheckedEuclid)
835    input a Stream<N>
836    input b Stream<N>
837    output quot Stream<Option<N>>
838)]
839pub async fn checked_euclid_div() {
840    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
841        check!(quot.send_one(a.checked_euclid_div(&b).into()).await)
842    }
843}
844
845/// Gives euclidian remainder of `a` divided by `b`, checking if division is possible or if overflow occurs
846///
847/// This function returns an option containing `a _mod_ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
848#[mel_function(
849    generic N (CheckedEuclid)
850)]
851pub fn checked_euclid_rem(a: N, b: N) -> Option<N> {
852    a.checked_euclid_rem(&b)
853}
854
855/// Gives euclidian remainder of division from two streams, checking if division is possible or if overflow occurs.
856///
857/// Remainder is computed for values passed through `a` divided by `b` and send in `rem`.
858/// This treatment outputs an option containing `a _mod_ b`, or none if division is not possible (as division by 0), or result cause overflow in data type.
859#[mel_treatment(
860    generic N (CheckedEuclid)
861    input a Stream<N>
862    input b Stream<N>
863    output rem Stream<Option<N>>
864)]
865pub async fn checked_euclid_rem() {
866    while let (Ok(a), Ok(b)) = (a.recv_one().await, b.recv_one().await) {
867        check!(rem.send_one(a.checked_euclid_rem(&b).into()).await)
868    }
869}