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}