1use crate::Assign;
18#[allow(unused_imports)]
19use crate::ops::{
20 AddFrom, BitAndFrom, BitOrFrom, BitXorFrom, DivFrom, DivRounding, DivRoundingAssign,
21 DivRoundingFrom, MulFrom, NegAssign, NotAssign, Pow, PowAssign, PowFrom, RemFrom, RemRounding,
22 RemRoundingAssign, RemRoundingFrom, ShlFrom, ShrFrom, SubFrom,
23};
24use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
25#[cfg(feature = "std")]
26use std::borrow::Cow;
27
28macro_rules! assign_from {
29 ($T:ty; $op:ident; $Imp:ident $method:ident) => {
30 impl $Imp for $T {
31 #[inline]
32 fn $method(&mut self, lhs: $T) {
33 *self = lhs.$op(*self);
34 }
35 }
36 impl $Imp<&$T> for $T {
37 #[inline]
38 fn $method(&mut self, lhs: &$T) {
39 *self = (*lhs).$op(*self);
40 }
41 }
42 };
43}
44macro_rules! int_ops {
45 ($($T:ty)*) => { $(
46 impl Assign for $T {
47 #[inline]
48 fn assign(&mut self, src: $T) {
49 *self = src;
50 }
51 }
52 impl Assign<&$T> for $T {
53 #[inline]
54 fn assign(&mut self, src: &$T) {
55 *self = *src;
56 }
57 }
58 impl NotAssign for $T {
59 #[inline]
60 fn not_assign(&mut self) {
61 *self = !*self;
62 }
63 }
64 #[cfg(not(feature = "num-traits"))]
65 impl Pow<u32> for $T {
66 type Output = $T;
67 #[inline]
68 fn pow(self, rhs: u32) -> $T {
69 self.pow(rhs)
70 }
71 }
72 #[cfg(not(feature = "num-traits"))]
73 impl Pow<u32> for &$T {
74 type Output = $T;
75 #[inline]
76 fn pow(self, rhs: u32) -> $T {
77 (*self).pow(rhs)
78 }
79 }
80 #[cfg(not(feature = "num-traits"))]
81 impl Pow<&u32> for $T {
82 type Output = $T;
83 #[inline]
84 fn pow(self, rhs: &u32) -> $T {
85 self.pow(*rhs)
86 }
87 }
88 #[cfg(not(feature = "num-traits"))]
89 impl Pow<&u32> for &$T {
90 type Output = $T;
91 #[inline]
92 fn pow(self, rhs: &u32) -> $T {
93 (*self).pow(*rhs)
94 }
95 }
96 impl PowAssign<u32> for $T {
97 #[inline]
98 fn pow_assign(&mut self, rhs: u32) {
99 *self = self.pow(rhs);
100 }
101 }
102 impl PowAssign<&u32> for $T {
103 #[inline]
104 fn pow_assign(&mut self, rhs: &u32) {
105 *self = self.pow(*rhs);
106 }
107 }
108 assign_from! { $T; add; AddFrom add_from }
109 assign_from! { $T; sub; SubFrom sub_from }
110 assign_from! { $T; mul; MulFrom mul_from }
111 assign_from! { $T; div; DivFrom div_from }
112 assign_from! { $T; rem; RemFrom rem_from }
113 assign_from! { $T; bitand; BitAndFrom bitand_from }
114 assign_from! { $T; bitor; BitOrFrom bitor_from }
115 assign_from! { $T; bitxor; BitXorFrom bitxor_from }
116 assign_from! { $T; shl; ShlFrom shl_from }
117 assign_from! { $T; shr; ShrFrom shr_from }
118 )* };
119}
120macro_rules! int_neg {
121 ($($T:ty)*) => { $(
122 impl NegAssign for $T {
123 #[inline]
124 fn neg_assign(&mut self) {
125 *self = -*self;
126 }
127 }
128 )* };
129}
130macro_rules! float_ops {
131 ($($T:ty)*) => { $(
132 impl Assign for $T {
133 #[inline]
134 fn assign(&mut self, src: $T) {
135 *self = src;
136 }
137 }
138 impl Assign<&$T> for $T {
139 #[inline]
140 fn assign(&mut self, src: &$T) {
141 *self = *src;
142 }
143 }
144 impl NegAssign for $T {
145 #[inline]
146 fn neg_assign(&mut self) {
147 *self = -*self;
148 }
149 }
150 #[cfg(feature = "std")]
151 #[cfg(not(feature = "num-traits"))]
152 impl Pow<i32> for $T {
153 type Output = $T;
154 #[inline]
155 fn pow(self, rhs: i32) -> $T {
156 self.powi(rhs)
157 }
158 }
159 #[cfg(feature = "std")]
160 #[cfg(not(feature = "num-traits"))]
161 impl Pow<i32> for &$T {
162 type Output = $T;
163 #[inline]
164 fn pow(self, rhs: i32) -> $T {
165 self.powi(rhs)
166 }
167 }
168 #[cfg(feature = "std")]
169 #[cfg(not(feature = "num-traits"))]
170 impl Pow<&i32> for $T {
171 type Output = $T;
172 #[inline]
173 fn pow(self, rhs: &i32) -> $T {
174 self.powi(*rhs)
175 }
176 }
177 #[cfg(feature = "std")]
178 #[cfg(not(feature = "num-traits"))]
179 impl Pow<&i32> for &$T {
180 type Output = $T;
181 #[inline]
182 fn pow(self, rhs: &i32) -> $T {
183 self.powi(*rhs)
184 }
185 }
186 #[cfg(feature = "std")]
187 impl PowAssign<i32> for $T {
188 #[inline]
189 fn pow_assign(&mut self, rhs: i32) {
190 *self = self.powi(rhs);
191 }
192 }
193 #[cfg(feature = "std")]
194 impl PowAssign<&i32> for $T {
195 #[inline]
196 fn pow_assign(&mut self, rhs: &i32) {
197 *self = self.powi(*rhs);
198 }
199 }
200 #[cfg(feature = "std")]
201 #[cfg(not(feature = "num-traits"))]
202 impl Pow<$T> for $T {
203 type Output = $T;
204 #[inline]
205 fn pow(self, rhs: $T) -> $T {
206 self.powf(rhs)
207 }
208 }
209 #[cfg(feature = "std")]
210 #[cfg(not(feature = "num-traits"))]
211 impl Pow<$T> for &$T {
212 type Output = $T;
213 #[inline]
214 fn pow(self, rhs: $T) -> $T {
215 self.powf(rhs)
216 }
217 }
218 #[cfg(feature = "std")]
219 #[cfg(not(feature = "num-traits"))]
220 impl Pow<&$T> for $T {
221 type Output = $T;
222 #[inline]
223 fn pow(self, rhs: &$T) -> $T {
224 self.powf(*rhs)
225 }
226 }
227 #[cfg(feature = "std")]
228 #[cfg(not(feature = "num-traits"))]
229 impl Pow<&$T> for &$T {
230 type Output = $T;
231 #[inline]
232 fn pow(self, rhs: &$T) -> $T {
233 self.powf(*rhs)
234 }
235 }
236 #[cfg(feature = "std")]
237 impl PowAssign<$T> for $T {
238 #[inline]
239 fn pow_assign(&mut self, rhs: $T) {
240 *self = self.powf(rhs);
241 }
242 }
243 #[cfg(feature = "std")]
244 impl PowAssign<&$T> for $T {
245 #[inline]
246 fn pow_assign(&mut self, rhs: &$T) {
247 *self = self.powf(*rhs);
248 }
249 }
250 assign_from! { $T; add; AddFrom add_from }
251 assign_from! { $T; sub; SubFrom sub_from }
252 assign_from! { $T; mul; MulFrom mul_from }
253 assign_from! { $T; div; DivFrom div_from }
254 assign_from! { $T; rem; RemFrom rem_from }
255 #[cfg(feature = "std")]
256 assign_from! { $T; pow; PowFrom pow_from }
257 )* };
258}
259
260macro_rules! rounding_fill {
261 (
262 $T:ty,
263 $Imp:ident
264 $ImpAssign:ident
265 $ImpFrom:ident,
266 $trunc:ident
267 $ceil:ident
268 $floor:ident
269 $euc:ident,
270 $trunc_ass:ident
271 $ceil_ass:ident
272 $floor_ass:ident
273 $euc_ass:ident,
274 $trunc_from:ident
275 $ceil_from:ident
276 $floor_from:ident
277 $euc_from:ident
278 ) => {
279 #[cfg(feature = "std")]
280 impl $Imp<&$T> for $T {
281 type Output = <$T as $Imp>::Output;
282 #[inline]
283 fn $trunc(self, rhs: &$T) -> Self::Output {
284 $Imp::$trunc(self, *rhs)
285 }
286 #[inline]
287 fn $ceil(self, rhs: &$T) -> Self::Output {
288 $Imp::$ceil(self, *rhs)
289 }
290 #[inline]
291 fn $floor(self, rhs: &$T) -> Self::Output {
292 $Imp::$floor(self, *rhs)
293 }
294 #[inline]
295 fn $euc(self, rhs: &$T) -> Self::Output {
296 $Imp::$euc(self, *rhs)
297 }
298 }
299
300 #[cfg(feature = "std")]
301 impl $Imp<$T> for &$T {
302 type Output = <$T as $Imp>::Output;
303 #[inline]
304 fn $trunc(self, rhs: $T) -> Self::Output {
305 $Imp::$trunc(*self, rhs)
306 }
307 #[inline]
308 fn $ceil(self, rhs: $T) -> Self::Output {
309 $Imp::$ceil(*self, rhs)
310 }
311 #[inline]
312 fn $floor(self, rhs: $T) -> Self::Output {
313 $Imp::$floor(*self, rhs)
314 }
315 #[inline]
316 fn $euc(self, rhs: $T) -> Self::Output {
317 $Imp::$euc(*self, rhs)
318 }
319 }
320
321 #[cfg(feature = "std")]
322 impl $Imp<&$T> for &$T {
323 type Output = <$T as $Imp>::Output;
324 #[inline]
325 fn $trunc(self, rhs: &$T) -> Self::Output {
326 $Imp::$trunc(*self, *rhs)
327 }
328 #[inline]
329 fn $ceil(self, rhs: &$T) -> Self::Output {
330 $Imp::$ceil(*self, *rhs)
331 }
332 #[inline]
333 fn $floor(self, rhs: &$T) -> Self::Output {
334 $Imp::$floor(*self, *rhs)
335 }
336 #[inline]
337 fn $euc(self, rhs: &$T) -> Self::Output {
338 $Imp::$euc(*self, *rhs)
339 }
340 }
341
342 #[cfg(feature = "std")]
343 impl $ImpAssign for $T {
344 #[inline]
345 fn $trunc_ass(&mut self, rhs: $T) {
346 *self = $Imp::$trunc(*self, rhs);
347 }
348 #[inline]
349 fn $ceil_ass(&mut self, rhs: $T) {
350 *self = $Imp::$ceil(*self, rhs);
351 }
352 #[inline]
353 fn $floor_ass(&mut self, rhs: $T) {
354 *self = $Imp::$floor(*self, rhs);
355 }
356 #[inline]
357 fn $euc_ass(&mut self, rhs: $T) {
358 *self = $Imp::$euc(*self, rhs);
359 }
360 }
361
362 #[cfg(feature = "std")]
363 impl $ImpAssign<&$T> for $T {
364 #[inline]
365 fn $trunc_ass(&mut self, rhs: &$T) {
366 *self = $Imp::$trunc(*self, *rhs);
367 }
368 #[inline]
369 fn $ceil_ass(&mut self, rhs: &$T) {
370 *self = $Imp::$ceil(*self, *rhs);
371 }
372 #[inline]
373 fn $floor_ass(&mut self, rhs: &$T) {
374 *self = $Imp::$floor(*self, *rhs);
375 }
376 #[inline]
377 fn $euc_ass(&mut self, rhs: &$T) {
378 *self = $Imp::$euc(*self, *rhs);
379 }
380 }
381
382 #[cfg(feature = "std")]
383 impl $ImpFrom for $T {
384 #[inline]
385 fn $trunc_from(&mut self, lhs: $T) {
386 *self = $Imp::$trunc(lhs, *self);
387 }
388 #[inline]
389 fn $ceil_from(&mut self, lhs: $T) {
390 *self = $Imp::$ceil(lhs, *self);
391 }
392 #[inline]
393 fn $floor_from(&mut self, lhs: $T) {
394 *self = $Imp::$floor(lhs, *self);
395 }
396 #[inline]
397 fn $euc_from(&mut self, lhs: $T) {
398 *self = $Imp::$euc(lhs, *self);
399 }
400 }
401
402 #[cfg(feature = "std")]
403 impl $ImpFrom<&$T> for $T {
404 #[inline]
405 fn $trunc_from(&mut self, lhs: &$T) {
406 *self = $Imp::$trunc(*lhs, *self);
407 }
408 #[inline]
409 fn $ceil_from(&mut self, lhs: &$T) {
410 *self = $Imp::$ceil(*lhs, *self);
411 }
412 #[inline]
413 fn $floor_from(&mut self, lhs: &$T) {
414 *self = $Imp::$floor(*lhs, *self);
415 }
416 #[inline]
417 fn $euc_from(&mut self, lhs: &$T) {
418 *self = $Imp::$euc(*lhs, *self);
419 }
420 }
421 };
422}
423
424macro_rules! rounding_signed {
425 ($($T:ty)*) => { $(
426 impl DivRounding for $T {
427 type Output = $T;
428 #[inline]
429 fn div_trunc(self, rhs: $T) -> $T {
430 self / rhs
431 }
432 #[inline]
433 fn div_ceil(self, rhs: $T) -> $T {
434 let (q, r) = (self / rhs, self % rhs);
435 let change = if rhs > 0 { r > 0 } else { r < 0 };
436 if change {
437 q + 1
438 } else {
439 q
440 }
441 }
442 #[inline]
443 fn div_floor(self, rhs: $T) -> $T {
444 let (q, r) = (self / rhs, self % rhs);
445 let change = if rhs > 0 { r < 0 } else { r > 0 };
446 if change {
447 q - 1
448 } else {
449 q
450 }
451 }
452 #[inline]
453 fn div_euc(self, rhs: $T) -> $T {
454 let (q, r) = (self / rhs, self % rhs);
455 if r < 0 {
456 if rhs < 0 {
457 q + 1
458 } else {
459 q - 1
460 }
461 } else {
462 q
463 }
464 }
465 }
466
467 rounding_fill! {
468 $T,
469 DivRounding DivRoundingAssign DivRoundingFrom,
470 div_trunc div_ceil div_floor div_euc,
471 div_trunc_assign div_ceil_assign div_floor_assign div_euc_assign,
472 div_trunc_from div_ceil_from div_floor_from div_euc_from
473 }
474
475 impl RemRounding for $T {
476 type Output = $T;
477 #[inline]
478 fn rem_trunc(self, rhs: $T) -> $T {
479 self % rhs
480 }
481 #[inline]
482 fn rem_ceil(self, rhs: $T) -> $T {
483 let r = self % rhs;
484 let change = if rhs > 0 { r > 0 } else { r < 0 };
485 if change {
486 r - rhs
487 } else {
488 r
489 }
490 }
491 #[inline]
492 fn rem_floor(self, rhs: $T) -> $T {
493 let r = self % rhs;
494 let change = if rhs > 0 { r < 0 } else { r > 0 };
495 if change {
496 r + rhs
497 } else {
498 r
499 }
500 }
501 #[inline]
502 fn rem_euc(self, rhs: $T) -> $T {
503 let r = self % rhs;
504 if r < 0 {
505 if rhs < 0 {
506 r - rhs
507 } else {
508 r + rhs
509 }
510 } else {
511 r
512 }
513 }
514 }
515
516 rounding_fill! {
517 $T,
518 RemRounding RemRoundingAssign RemRoundingFrom,
519 rem_trunc rem_ceil rem_floor rem_euc,
520 rem_trunc_assign rem_ceil_assign rem_floor_assign rem_euc_assign,
521 rem_trunc_from rem_ceil_from rem_floor_from rem_euc_from
522 }
523
524 )* };
525}
526
527macro_rules! rounding_unsigned {
528 ($($T:ty)*) => { $(
529 impl DivRounding for $T {
530 type Output = $T;
531 #[inline]
532 fn div_trunc(self, rhs: $T) -> $T {
533 self / rhs
534 }
535 #[inline]
536 fn div_ceil(self, rhs: $T) -> $T {
537 let (q, r) = (self / rhs, self % rhs);
538 if r > 0 {
539 q + 1
540 } else {
541 q
542 }
543 }
544 #[inline]
545 fn div_floor(self, rhs: $T) -> $T {
546 self / rhs
547 }
548 #[inline]
549 fn div_euc(self, rhs: $T) -> $T {
550 self / rhs
551 }
552 }
553
554 rounding_fill! {
555 $T,
556 DivRounding DivRoundingAssign DivRoundingFrom,
557 div_trunc div_ceil div_floor div_euc,
558 div_trunc_assign div_ceil_assign div_floor_assign div_euc_assign,
559 div_trunc_from div_ceil_from div_floor_from div_euc_from
560 }
561 )* };
562}
563
564macro_rules! rounding_float {
565 ($($T:ty)*) => { $(
566 #[cfg(feature = "std")]
567 impl DivRounding for $T {
568 type Output = $T;
569 #[inline]
570 fn div_trunc(self, rhs: $T) -> $T {
571 (self / rhs).trunc()
572 }
573 #[inline]
574 fn div_ceil(self, rhs: $T) -> $T {
575 let (q, r) = ((self / rhs).trunc(), self % rhs);
576 let change = if rhs > 0.0 { r > 0.0 } else { r < 0.0 };
577 if change {
578 q + 1.0
579 } else {
580 q
581 }
582 }
583 #[inline]
584 fn div_floor(self, rhs: $T) -> $T {
585 let (q, r) = ((self / rhs).trunc(), self % rhs);
586 let change = if rhs > 0.0 { r < 0.0 } else { r > 0.0 };
587 if change {
588 q - 1.0
589 } else {
590 q
591 }
592 }
593 #[inline]
594 fn div_euc(self, rhs: $T) -> $T {
595 let (q, r) = ((self / rhs).trunc(), self % rhs);
596 if r < 0.0 {
597 if rhs < 0.0 {
598 q + 1.0
599 } else {
600 q - 1.0
601 }
602 } else {
603 q
604 }
605 }
606 }
607
608 rounding_fill! {
609 $T,
610 DivRounding DivRoundingAssign DivRoundingFrom,
611 div_trunc div_ceil div_floor div_euc,
612 div_trunc_assign div_ceil_assign div_floor_assign div_euc_assign,
613 div_trunc_from div_ceil_from div_floor_from div_euc_from
614 }
615
616 impl RemRounding for $T {
617 type Output = $T;
618 #[inline]
619 fn rem_trunc(self, rhs: $T) -> $T {
620 self % rhs
621 }
622 #[inline]
623 fn rem_ceil(self, rhs: $T) -> $T {
624 let r = self % rhs;
625 let change = if rhs > 0.0 { r > 0.0 } else { r < 0.0 };
626 if change {
627 r - rhs
628 } else {
629 r
630 }
631 }
632 #[inline]
633 fn rem_floor(self, rhs: $T) -> $T {
634 let r = self % rhs;
635 let change = if rhs > 0.0 { r < 0.0 } else { r > 0.0 };
636 if change {
637 r + rhs
638 } else {
639 r
640 }
641 }
642 #[inline]
643 fn rem_euc(self, rhs: $T) -> $T {
644 let r = self % rhs;
645 if r < 0.0 {
646 if rhs < 0.0 {
647 r - rhs
648 } else {
649 r + rhs
650 }
651 } else {
652 r
653 }
654 }
655 }
656
657 rounding_fill! {
658 $T,
659 RemRounding RemRoundingAssign RemRoundingFrom,
660 rem_trunc rem_ceil rem_floor rem_euc,
661 rem_trunc_assign rem_ceil_assign rem_floor_assign rem_euc_assign,
662 rem_trunc_from rem_ceil_from rem_floor_from rem_euc_from
663 }
664
665 )* };
666}
667
668impl NotAssign for bool {
669 #[inline]
670 fn not_assign(&mut self) {
671 *self = !*self;
672 }
673}
674assign_from! { bool; bitand; BitAndFrom bitand_from }
675assign_from! { bool; bitor; BitOrFrom bitor_from }
676assign_from! { bool; bitxor; BitXorFrom bitxor_from }
677
678int_ops! { i8 i16 i32 i64 i128 isize }
679int_ops! { u8 u16 u32 u64 u128 usize }
680int_neg! { i8 i16 i32 i64 i128 isize }
681assign_from! { u32; pow; PowFrom pow_from }
682float_ops! { f32 f64 }
683
684rounding_signed! { i8 i16 i32 i64 i128 isize }
685
686rounding_unsigned! { u8 u16 u32 u64 u128 usize }
695
696rounding_float! { f32 f64 }
697
698#[cfg(feature = "std")]
699impl Assign<&str> for String {
700 #[inline]
701 fn assign(&mut self, src: &str) {
702 self.clear();
703 self.push_str(src);
704 }
705}
706
707#[cfg(feature = "std")]
708impl<'a> Assign<&'a str> for Cow<'a, str> {
709 #[inline]
710 fn assign(&mut self, src: &'a str) {
711 *self = Cow::Borrowed(src);
712 }
713}
714
715#[cfg(feature = "std")]
716impl<'a> Assign<Cow<'a, str>> for Cow<'a, str> {
717 #[inline]
718 fn assign(&mut self, src: Cow<'a, str>) {
719 *self = src;
720 }
721}
722
723#[cfg(feature = "std")]
724impl AddFrom<&str> for String {
725 #[inline]
726 fn add_from(&mut self, lhs: &str) {
727 self.insert_str(0, lhs);
728 }
729}
730
731#[cfg(feature = "std")]
732impl<'a> AddFrom<&'a str> for Cow<'a, str> {
733 fn add_from(&mut self, lhs: &'a str) {
734 if lhs.is_empty() {
735 } else if self.is_empty() {
736 *self = Cow::Borrowed(lhs);
737 } else {
738 match *self {
739 Cow::Borrowed(rhs) => {
740 let mut s = String::with_capacity(lhs.len() + rhs.len());
741 s.push_str(lhs);
742 s.push_str(rhs);
743 *self = Cow::Owned(s);
744 }
745 Cow::Owned(ref mut s) => {
746 s.insert_str(0, lhs);
747 }
748 }
749 }
750 }
751}
752
753#[cfg(feature = "std")]
754impl<'a> AddFrom<Cow<'a, str>> for Cow<'a, str> {
755 fn add_from(&mut self, lhs: Cow<'a, str>) {
756 if lhs.is_empty() {
757 } else if self.is_empty() {
758 *self = lhs;
759 } else {
760 match *self {
761 Cow::Borrowed(rhs) => {
762 let mut s = String::with_capacity(lhs.len() + rhs.len());
763 s.push_str(&lhs);
764 s.push_str(rhs);
765 *self = Cow::Owned(s);
766 }
767 Cow::Owned(ref mut s) => {
768 s.insert_str(0, &lhs);
769 }
770 }
771 }
772 }
773}