1macro_rules! default {
22 ($op:ident, ctx, $out_ty:ident, $in:ident) => {
24 $out_ty::zero($in.context())
25 };
26 ($op:ident, ctx_in, $out_ty:ident, $in:ident) => {
27 $out_ty::zero()
28 };
29 ($op:ident, matrix, $out_ty:ident, $in:ident) => {
30 $out_ty::zero($in.nrows_si(), $in.ncols_si())
31 };
32 ($op:ident, matrix_ctx, $out_ty:ident, $in:ident) => {
33 $out_ty::zero($in.nrows_si(), $in.ncols_si(), $in.context())
34 };
35 ($op:ident, matrix_ctx_new_only, $out_ty:ident, $in:ident) => {
36 $out_ty::zero($in.nrows_si(), $in.ncols_si(), $in.context())
37 };
38 ($op:ident, $kw:ident, $out_ty:ident, $in:ident) => {
39 $out_ty::default()
40 };
41
42 ($op:ident, ctx, $out_ty:ident, $lhs:ident, $rhs:ident) => {
44 $out_ty::zero($lhs.context())
45 };
46 ($op:ident, ctx_lhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
47 $out_ty::zero($lhs.context())
48 };
49 ($op:ident, ctx_rhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
50 $out_ty::zero($rhs.context())
51 };
52 ($op:ident, matrix, $out_ty:ident, $lhs:ident, $rhs:ident) => {
53 $out_ty::zero($lhs.nrows_si(), $rhs.ncols_si())
54 };
55 ($op:ident, matrix_ctx, $out_ty:ident, $lhs:ident, $rhs:ident) => {
56 $out_ty::zero($lhs.nrows_si(), $rhs.ncols_si(), $lhs.context())
57 };
58 ($op:ident, matrix_ctx_new_only, $out_ty:ident, $lhs:ident, $rhs:ident) => {
67 $out_ty::zero($lhs.nrows_si(), $rhs.ncols_si(), $lhs.context())
68 };
69 ($op:ident, scalar_lhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
70 $out_ty::zero($rhs.nrows_si(), $rhs.ncols_si())
71 };
72 ($op:ident, scalar_rhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
73 $out_ty::zero($lhs.nrows_si(), $lhs.ncols_si())
74 };
75 ($op:ident, $kw:ident, $out_ty:ident, $lhs:ident, $rhs:ident) => {
76 $out_ty::default()
77 };
78}
79
80macro_rules! op_guard {
81 (Inv, $kw:ident, $out_ty:ident, $in:ident) => {
83 };
86 (Pow, $kw:ident, $out_ty:ident, $in:ident) => {
87 };
89 ($op:ident, $kw:ident, $out_ty:ident, $in:ident) => {
90 };
91
92 ($op:ident, ctx, $out_ty:ident, $lhs:ident, $rhs:ident) => {
94 assert_eq!($lhs.context(), $rhs.context())
96 };
97 (Mul, matrix, $out_ty:ident, $lhs:ident, $rhs:ident) => {
98 assert_eq!($lhs.ncols_si(), $rhs.nrows_si())
99 };
100 (MulAssign, matrix, $out_ty:ident, $lhs:ident, $rhs:ident) => {
101 assert_eq!($lhs.ncols_si(), $rhs.nrows_si())
102 };
103 ($op:ident, matrix, $out_ty:ident, $lhs:ident, $rhs:ident) => {
105 assert_eq!($lhs.nrows_si(), $rhs.nrows_si());
106 assert_eq!($lhs.ncols_si(), $rhs.ncols_si())
107 };
108 ($op:ident, scalar_lhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
109 };
110 (Div, scalar_rhs, $out_ty:ident, $lhs:ident, $rhs:ident) => {
111 };
114 ($op:ident, $kw:ident, $out_ty:ident, $lhs:ident, $rhs:ident) => {
115 };
116}
117
118macro_rules! call_unsafe {
119 (ctx, $func:path, $out:ident, $in:ident) => {
121 unsafe {
122 $func($out.as_mut_ptr(), $in.as_ptr(), $out.ctx_as_ptr());
123 }
124 };
125 (matrix_ctx, $func:path, $out:ident, $in:ident) => {
126 unsafe {
127 $func($out.as_mut_ptr(), $in.as_ptr(), $out.ctx_as_ptr());
128 }
129 };
130 (ctx_in, $func:path, $out:ident, $in:ident) => {
131 unsafe {
132 $func($out.as_mut_ptr(), $in.as_ptr(), $in.ctx_as_ptr());
133 }
134 };
135 ($kw:ident, $func:path, $out:ident, $in:ident) => {
136 unsafe {
137 $func($out.as_mut_ptr(), $in.as_ptr());
138 }
139 };
140 (cast ctx, $func:path, $cast:ty, $out:ident, $in:ident) => {
141 unsafe {
142 $func($out.as_mut_ptr(), *$in as $cast, $out.ctx_as_ptr());
143 }
144 };
145 (cast $kw:ident, $func:path, $cast:ty, $out:ident, $in:ident) => {
146 unsafe {
147 $func($out.as_mut_ptr(), *$in as $cast);
148 }
149 };
150
151 (ctx, $func:path, $out:ident, $lhs:ident, $rhs:ident) => {
153 unsafe {
154 $func(
155 $out.as_mut_ptr(),
156 $lhs.as_ptr(),
157 $rhs.as_ptr(),
158 $lhs.ctx_as_ptr(),
159 );
160 }
161 };
162 (ctx_lhs, $func:path, $out:ident, $lhs:ident, $rhs:ident) => {
163 unsafe {
164 $func(
165 $out.as_mut_ptr(),
166 $lhs.as_ptr(),
167 $rhs.as_ptr(),
168 $lhs.ctx_as_ptr(),
169 );
170 }
171 };
172 (ctx_rhs, $func:path, $out:ident, $lhs:ident, $rhs:ident) => {
173 unsafe {
174 $func(
175 $out.as_mut_ptr(),
176 $lhs.as_ptr(),
177 $rhs.as_ptr(),
178 $rhs.ctx_as_ptr(),
179 );
180 }
181 };
182 (matrix_ctx, $func:path, $out:ident, $lhs:ident, $rhs:ident) => {
183 unsafe {
184 $func(
185 $out.as_mut_ptr(),
186 $lhs.as_ptr(),
187 $rhs.as_ptr(),
188 $lhs.ctx_as_ptr(),
189 );
190 }
191 };
192 ($kw:ident, $func:path, $out:ident, $lhs:ident, $rhs:ident) => {
193 unsafe {
194 $func($out.as_mut_ptr(), $lhs.as_ptr(), $rhs.as_ptr());
195 }
196 };
197
198 (cast_rhs ctx_lhs, $func:path, $cast:ty, $out:ident, $lhs:ident, $rhs:ident) => {
200 unsafe {
201 $func(
202 $out.as_mut_ptr(),
203 $lhs.as_ptr(),
204 *$rhs as $cast,
205 $lhs.ctx_as_ptr(),
206 );
207 }
208 };
209 (cast_rhs $kw:ident, $func:path, $cast:ty, $out:ident, $lhs:ident, $rhs:ident) => {
210 unsafe {
211 $func($out.as_mut_ptr(), $lhs.as_ptr(), *$rhs as $cast);
212 }
213 };
214 (cast_lhs ctx_rhs, $func:path, $cast:ty, $out:ident, $lhs:ident, $rhs:ident) => {
215 unsafe {
216 $func(
217 $out.as_mut_ptr(),
218 *$lhs as $cast,
219 $rhs.as_ptr(),
220 $rhs.ctx_as_ptr(),
221 );
222 }
223 };
224 (cast_lhs $kw:ident, $func:path, $cast:ty, $out:ident, $lhs:ident, $rhs:ident) => {
225 unsafe {
226 $func($out.as_mut_ptr(), *$lhs as $cast, $rhs.as_ptr());
227 }
228 };
229}
230
231#[macro_export]
233macro_rules! impl_cmp {
234 (
236 eq
237 $t:ident
238 {
239 $($code:tt)*
240 }
241 ) => {
242 impl Eq for $t {}
243
244 impl PartialEq for $t {
247 #[inline]
248 $($code)*
249 }
250
251 impl PartialEq<&$t> for $t {
252 #[inline]
253 fn eq(&self, rhs: &&$t) -> bool {
254 rhs.eq(&self)
255 }
256 }
257
258 impl PartialEq<$t> for &$t {
259 #[inline]
260 fn eq(&self, rhs: &$t) -> bool {
261 self.eq(&rhs)
262 }
263 }
264 };
265 (
266 partial_eq
267 $t:ident
268 {
269 $($code:tt)*
270 }
271 ) => {
272 impl_cmp! {
273 partial_eq
274 $t, $t
275 {
276 $($code)*
277 }
278 }
279 };
280 (
282 ord
283 $t:ident
284 {
285 $($code:tt)*
286 }
287 ) => {
288 impl Ord for $t {
289 #[inline]
290 $($code)*
291 }
292
293 impl PartialOrd for $t {
294 #[inline]
295 fn partial_cmp(&self, rhs: &$t) -> Option<Ordering> {
296 Some(self.cmp(rhs))
297 }
298 }
299 };
300 (
301 partial_ord
302 $t:ident
303 {
304 $($code:tt)*
305 }
306 ) => {
307 impl_cmp! {
308 partial_ord
309 $t, $t
310 {
311 $($code)*
312 }
313 }
314 };
315 (
317 partial_eq
318 $t1:ident, $t2:ident
319 {
320 $($code:tt)*
321 }
322 ) => {
323 impl PartialEq<$t2> for $t1 {
324 #[inline]
325 $($code)*
326 }
327
328 impl PartialEq<&$t2> for $t1 {
329 #[inline]
330 fn eq(&self, rhs: &&$t2) -> bool {
331 (&self).eq(rhs)
332 }
333 }
334
335 impl PartialEq<$t2> for &$t1 {
336 #[inline]
337 fn eq(&self, rhs: &$t2) -> bool {
338 self.eq(&rhs)
339 }
340 }
341 };
342 (
344 partial_ord
345 $t1:ident, $t2:ident
346 {
347 $($code:tt)*
348 }
349 ) => {
350 impl PartialOrd<$t2> for $t1 {
351 #[inline]
352 $($code)*
353 }
354 };
355
356}
357
358macro_rules! impl_cmp_unsafe {
360 (
361 eq
362 $t:ident
363 $func:path
364 ) => {
365 impl_cmp! {
366 eq
367 $t
368 {
369 fn eq(&self, rhs: &$t) -> bool {
370 unsafe { $func(self.as_ptr(), rhs.as_ptr()) != 0 }
371 }
372 }
373 }
374 };
375 (
376 partial_eq
377 $t1:ident, $t2:ident
378 $func:path
379 ) => {
380 impl_cmp! {
381 partial_eq
382 $t1, $t2
383 {
384 fn eq(&self, rhs: &$t2) -> bool {
385 unsafe { $func(self.as_ptr(), rhs.as_ptr()) != 0 }
386 }
387 }
388 }
389 impl_cmp! {
390 partial_eq
391 $t2, $t1
392 {
393 fn eq(&self, rhs: &$t1) -> bool {
394 unsafe { $func(rhs.as_ptr(), self.as_ptr()) != 0 }
395 }
396 }
397 }
398 };
399 (
400 partial_eq
401 $t1:ident, $cast:ident {$($t2:ident)+}
402 $func:path
403 ) => ($(
404 impl_cmp! {
405 partial_eq
406 $t1, $t2
407 {
408 fn eq(&self, rhs: &$t2) -> bool {
409 unsafe { $func(self.as_ptr(), *rhs as $cast) != 0 }
410 }
411 }
412 }
413 impl_cmp! {
414 partial_eq
415 $t2, $t1
416 {
417 fn eq(&self, rhs: &$t1) -> bool {
418 unsafe { $func(rhs.as_ptr(), *self as $cast) != 0 }
419 }
420 }
421 }
422 )+);
423 (
424 ord
425 $t:ident
426 $func:path
427 ) => {
428 impl_cmp! {
429 ord
430 $t
431 {
432 fn cmp(&self, rhs: &$t) -> Ordering {
433 let cmp = unsafe { $func(self.as_ptr(), rhs.as_ptr()) };
434 if cmp == 0 {
435 Equal
436 } else if cmp < 0 {
437 Less
438 } else {
439 Greater
440 }
441 }
442 }
443 }
444 };
445 (
446 partial_ord
447 $t1:ident, $t2:ident
448 $func:path
449 ) => {
450 impl_cmp! {
451 partial_ord
452 $t1, $t2
453 {
454 fn partial_cmp(&self, rhs: &$t2) -> Option<Ordering> {
455 let cmp = unsafe { $func(self.as_ptr(), rhs.as_ptr()) };
456 if cmp == 0 {
457 Some(Equal)
458 } else if cmp < 0 {
459 Some(Less)
460 } else {
461 Some(Greater)
462 }
463 }
464 }
465 }
466 impl_cmp! {
467 partial_ord
468 $t2, $t1
469 {
470 fn partial_cmp(&self, rhs: &$t1) -> Option<Ordering> {
471 let cmp = unsafe { $func(rhs.as_ptr(), self.as_ptr()) };
472 if cmp == 0 {
473 Some(Equal)
474 } else if cmp > 0 {
475 Some(Less)
476 } else {
477 Some(Greater)
478 }
479 }
480 }
481 }
482 };
483 (
484 partial_ord
485 $t1:ident, $cast:ident {$($t2:ident)+}
486 $func:path
487 ) => ($(
488 impl_cmp! {
489 partial_ord
490 $t1, $t2
491 {
492 fn partial_cmp(&self, rhs: &$t2) -> Option<Ordering> {
493 let cmp = unsafe { $func(self.as_ptr(), *rhs as $cast) };
494 if cmp == 0 {
495 Some(Equal)
496 } else if cmp < 0 {
497 Some(Less)
498 } else {
499 Some(Greater)
500 }
501 }
502 }
503 }
504 impl_cmp! {
505 partial_ord
506 $t2, $t1
507 {
508 fn partial_cmp(&self, rhs: &$t1) -> Option<Ordering> {
509 let cmp = unsafe { $func(rhs.as_ptr(), *self as $cast) };
510 if cmp == 0 {
511 Some(Equal)
512 } else if cmp > 0 {
513 Some(Less)
514 } else {
515 Some(Greater)
516 }
517 }
518 }
519 }
520 )+)
521}
522
523#[macro_export]
525macro_rules! impl_unop {
526 (
527 $t:ident
529 $op:ident {$meth:ident}
530 {
531 $($code:tt)*
532 }
533 $op_assign:ident {$meth_assign:ident}
534 {
535 $($code_assign:tt)*
536 }
537 ) => {
538 impl $op for $t {
539 type Output = $t;
540 #[inline]
541 fn $meth(mut self) -> $t {
542 self.$meth_assign();
543 self
544 }
545 }
546
547 impl $op for &$t {
548 type Output = $t;
549 #[inline]
550 $($code)*
551 }
552
553 impl $op_assign for $t {
554 #[inline]
555 $($code_assign)*
556 }
557 };
558 (
559 $t:ident, $out:ident
561 $op:ident {$meth:ident}
562 {
563 $($code:tt)*
564 }
565 ) => {
566 impl $op for $t {
567 type Output = $out;
568 #[inline]
569 $($code)*
570 }
571
572 impl $op for &$t {
573 type Output = $out;
574 #[inline]
575 $($code)*
576 }
577 };
578 (
579 $t:ident, Option<$out:ident>
581 $op:ident {$meth:ident}
582 {
583 $($code:tt)*
584 }
585 ) => {
586 impl $op for $t {
587 type Output = Option<$out>;
588 #[inline]
589 $($code)*
590 }
591
592 impl $op for &$t {
593 type Output = Option<$out>;
594 #[inline]
595 $($code)*
596 }
597 };
598}
599
600macro_rules! impl_unop_unsafe {
602 (
603 $kw:ident
604 $t:ident
605 $op:ident {$meth:ident}
606 $op_assign:ident {$meth_assign:ident}
607 $func:path
608 ) => {
609 impl_unop! {
610 $t
611 $op {$meth}
612 {
613 fn $meth(self) -> $t {
614 let mut res = default!($op, $kw, $t, self);
615 call_unsafe!($kw, $func, res, self);
616 res
617 }
618 }
619 $op_assign {$meth_assign}
620 {
621 fn $meth_assign(&mut self) {
622 call_unsafe!($kw, $func, self, self);
623 }
624 }
625 }
626 };
627 (
628 $kw:ident
629 $t:ident, $out:ident
630 $op:ident {$meth:ident}
631 $func:path
632 ) => {
633 impl_unop! {
634 $t, $out
635 $op {$meth}
636 {
637 fn $meth(self) -> $out {
638 let mut res = default!($op, $kw, $out, self);
639 call_unsafe!($kw, $func, res, self);
641 res
642 }
643 }
644 }
645 };
646}
647
648#[macro_export]
650macro_rules! impl_binop {
651 (
652 $t1:ident, $t2:ident, $out:ident
654 $(
655 $op:ident {$meth:ident}
656 {
657 $($code:tt)*
658 }
659 $op_assign:ident {$meth_assign:ident}
660 {
661 $($code_assign:tt)*
662 }
663 $op_from:ident {$meth_from:ident}
664 {
665 $($code_from:tt)*
666 }
667 $assign_op:ident {$assign_meth:ident}
668 {
669 $($assign_code:tt)*
670 }
671 )*
672 ) => ($(
673
674 impl $op<&$t2> for &$t1 {
675 type Output = $out;
676 #[inline]
677 $($code)*
678 }
679
680 impl $op<$t2> for &$t1 {
681 type Output = $out;
682 #[inline]
683 fn $meth(self, mut rhs: $t2) -> $out {
684 rhs.$meth_from(self);
685 rhs
686 }
687 }
688
689 impl $op<&$t2> for $t1 {
690 type Output = $out;
691 #[inline]
692 fn $meth(mut self, rhs: &$t2) -> $out {
693 self.$meth_assign(rhs);
694 self
695 }
696 }
697
698 impl $op<$t2> for $t1 {
699 type Output = $out;
700 #[inline]
701 fn $meth(mut self, rhs: $t2) -> $out {
702 self.$meth_assign(&rhs);
703 self
704 }
705 }
706
707 impl_binop! {@op_assign
708 $t1, $t2, $out
709 $op_assign {$meth_assign}
710 {
711 $($code_assign)*
712 }
713 }
714
715 impl_binop! {@op_from
716 $t1, $t2, $out
717 $op_from {$meth_from}
718 {
719 $($code_from)*
720 }
721 }
722
723 impl_binop! {@assign_op
724 $t1, $t2, $out
725 $assign_op {$assign_meth}
726 {
727 $($assign_code)*
728 }
729 }
730 )*);
731 (
732 op_assign
734 $t1:ident, $t2:ident, $out:ident
735 $(
736 $op:ident {$meth:ident}
737 {
738 $($code:tt)*
739 }
740 $op_assign:ident {$meth_assign:ident}
741 {
742 $($code_assign:tt)*
743 }
744 $assign_op:ident {$assign_meth:ident}
745 {
746 $($assign_code:tt)*
747 }
748 )*
749 ) => ($(
750
751 impl $op<&$t2> for &$t1 {
752 type Output = $out;
753 #[inline]
754 $($code)*
755 }
756
757 impl $op<$t2> for &$t1 {
758 type Output = $out;
759 #[inline]
760 fn $meth(self, rhs: $t2) -> $out {
761 self.$meth(&rhs)
762 }
763 }
764
765 impl $op<&$t2> for $t1 {
766 type Output = $out;
767 #[inline]
768 fn $meth(mut self, rhs: &$t2) -> $out {
769 self.$meth_assign(rhs);
770 self
771 }
772 }
773
774 impl $op<$t2> for $t1 {
775 type Output = $out;
776 #[inline]
777 fn $meth(mut self, rhs: $t2) -> $out {
778 self.$meth_assign(&rhs);
779 self
780 }
781 }
782
783 impl_binop! {@op_assign
784 $t1, $t2, $out
785 $op_assign {$meth_assign}
786 {
787 $($code_assign)*
788 }
789 }
790
791 impl_binop! {@assign_op
792 $t1, $t2, $out
793 $assign_op {$assign_meth}
794 {
795 $($assign_code)*
796 }
797 }
798 )*);
799 (
800 op_from
802 $t1:ident, $t2:ident, $out:ident
803 $(
804 $op:ident {$meth:ident}
805 {
806 $($code:tt)*
807 }
808 $op_from:ident {$meth_from:ident}
809 {
810 $($code_from:tt)*
811 }
812 $assign_op:ident {$assign_meth:ident}
813 {
814 $($assign_code:tt)*
815 }
816 )*
817 ) => ($(
818
819 impl $op<&$t2> for &$t1 {
820 type Output = $out;
821 #[inline]
822 $($code)*
823 }
824
825 impl $op<$t2> for &$t1 {
826 type Output = $out;
827 #[inline]
828 fn $meth(self, mut rhs: $t2) -> $out {
829 rhs.$meth_from(self);
830 rhs
831 }
832 }
833
834 impl $op<&$t2> for $t1 {
835 type Output = $out;
836 #[inline]
837 fn $meth(self, rhs: &$t2) -> $out {
838 (&self).$meth(rhs)
839 }
840 }
841
842 impl $op<$t2> for $t1 {
843 type Output = $out;
844 #[inline]
845 fn $meth(self, mut rhs: $t2) -> $out {
846 rhs.$meth_from(self);
847 rhs
848 }
849 }
850
851 impl_binop! {@op_from
852 $t1, $t2, $out
853 $op_from {$meth_from}
854 {
855 $($code_from)*
856 }
857 }
858 impl_binop! {@assign_op
859 $t1, $t2, $out
860 $assign_op {$assign_meth}
861 {
862 $($assign_code)*
863 }
864 }
865 )*);
866 (
867 $t1:ident, $t2:ident, $out:ident
869 $(
870 $op:ident {$meth:ident}
871 {
872 $($code:tt)*
873 }
874 $assign_op:ident {$assign_meth:ident}
875 {
876 $($assign_code:tt)*
877 }
878 )*
879 ) => ($(
880 impl $op<&$t2> for &$t1 {
881 type Output = $out;
882 #[inline]
883 $($code)*
884 }
885
886 impl $op<$t2> for &$t1 {
887 type Output = $out;
888 #[inline]
889 fn $meth(self, rhs: $t2) -> $out {
890 self.$meth(&rhs)
891 }
892 }
893
894 impl $op<&$t2> for $t1 {
895 type Output = $out;
896 #[inline]
897 fn $meth(self, rhs: &$t2) -> $out {
898 (&self).$meth(rhs)
899 }
900 }
901
902 impl $op<$t2> for $t1 {
903 type Output = $out;
904 #[inline]
905 fn $meth(self, rhs: $t2) -> $out {
906 (&self).$meth(&rhs)
907 }
908 }
909
910 impl_binop! {@assign_op
911 $t1, $t2, $out
912 $assign_op {$assign_meth}
913 {
914 $($assign_code)*
915 }
916 }
917 )*);
918 (
919 @op_assign
920 $t1:ident, $t2:ident, $out:ident
921 $op_assign:ident {$meth_assign:ident}
922 {
923 $($code_assign:tt)*
924 }
925 ) => {
926 impl $op_assign<&$t2> for $t1 {
927 #[inline]
928 $($code_assign)*
929 }
930
931 impl $op_assign<$t2> for $t1 {
932 #[inline]
933 fn $meth_assign(&mut self, rhs: $t2) {
934 self.$meth_assign(&rhs);
935 }
936 }
937 };
938 (
939 @op_from
940 $t1:ident, $t2:ident, $out:ident
941 $op_from:ident {$meth_from:ident}
942 {
943 $($code_from:tt)*
944 }
945 ) => {
946 impl $op_from<&$t1> for $t2 {
947 #[inline]
948 $($code_from)*
949 }
950
951 impl $op_from<$t1> for $t2 {
952 #[inline]
953 fn $meth_from(&mut self, lhs: $t1) {
954 self.$meth_from(&lhs);
955 }
956 }
957 };
958 (
959 @assign_op
960 $t1:ident, $t2:ident, $out:ident
961 $assign_op:ident {$assign_meth:ident}
962 {
963 $($assign_code:tt)*
964 }
965 ) => {
966 impl $assign_op<&$t1, &$t2> for $out {
967 #[inline]
968 $($assign_code)*
969 }
970
971 impl $assign_op<$t1, &$t2> for $out {
972 #[inline]
973 fn $assign_meth(&mut self, lhs: $t1, rhs: &$t2) {
974 self.$assign_meth(&lhs, rhs);
975 }
976 }
977
978 impl $assign_op<&$t1, $t2> for $out {
979 #[inline]
980 fn $assign_meth(&mut self, lhs: &$t1, rhs: $t2) {
981 self.$assign_meth(lhs, &rhs);
982 }
983 }
984
985 impl $assign_op<$t1, $t2> for $out {
986 #[inline]
987 fn $assign_meth(&mut self, lhs: $t1, rhs: $t2) {
988 self.$assign_meth(&lhs, &rhs);
989 }
990 }
991 };
992}
993
994macro_rules! impl_binop_unsafe {
996 (
997 $kw:ident
999 $t1:ident, $t2:ident, $out:ident
1000 $(
1001 $op:ident {$meth:ident}
1002 $op_assign:ident {$meth_assign:ident}
1003 $op_from:ident {$meth_from:ident}
1004 $assign_op:ident {$assign_meth:ident}
1005 $func:path;
1006 )+
1007 ) => ($(
1008 impl_binop! {
1009 $t1, $t2, $out
1010 $op {$meth}
1011 {
1012 fn $meth(self, rhs: &$t2) -> $out {
1013 op_guard!($op, $kw, $out, self, rhs);
1014 let mut res = default!($op, $kw, $out, self, rhs);
1015 call_unsafe!($kw, $func, res, self, rhs);
1016 res
1017 }
1018 }
1019 $op_assign {$meth_assign}
1020 {
1021 fn $meth_assign(&mut self, rhs: &$t2) {
1022 op_guard!($op, $kw, $out, self, rhs);
1023 call_unsafe!($kw, $func, self, self, rhs);
1024 }
1025 }
1026 $op_from {$meth_from}
1027 {
1028 fn $meth_from(&mut self, lhs: &$t2) {
1029 op_guard!($op, $kw, $out, lhs, self);
1030 call_unsafe!($kw, $func, self, lhs, self);
1031 }
1032 }
1033 $assign_op {$assign_meth}
1034 {
1035 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1036 op_guard!($op, $kw, $out, lhs, rhs);
1037 call_unsafe!($kw, $func, self, lhs, rhs);
1038 }
1039 }
1040 }
1041 )+);
1042 (
1043 $kw:ident
1045 op_assign
1046 $t1:ident, $t2:ident, $out:ident
1047 $(
1048 $op:ident {$meth:ident}
1049 $op_assign:ident {$meth_assign:ident}
1050 $assign_op:ident {$assign_meth:ident}
1051 $func:path;
1052 )+
1053 ) => ($(
1054 impl_binop! {
1055 op_assign
1056 $t1, $t2, $out
1057 $op {$meth}
1058 {
1059 fn $meth(self, rhs: &$t2) -> $out {
1060 let mut res = default!($op, $kw, $out, self, rhs);
1061 call_unsafe!($kw, $func, res, self, rhs);
1062 res
1063 }
1064 }
1065 $op_assign {$meth_assign}
1066 {
1067 fn $meth_assign(&mut self, rhs: &$t2) {
1068 call_unsafe!($kw, $func, self, self, rhs);
1069 }
1070 }
1071 $assign_op {$assign_meth}
1072 {
1073 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1074 call_unsafe!($kw, $func, self, lhs, rhs);
1075 }
1076 }
1077 }
1078 )+);
1079 (
1080 $kw:ident
1082 op_assign
1083 $t1:ident, $cast:ty {$($t2:ident)+}, $out:ident
1084
1085 $op:ident {$meth:ident}
1086 $op_assign:ident {$meth_assign:ident}
1087 $assign_op:ident {$assign_meth:ident}
1088 $func:path;
1089
1090 $($next:tt)*
1091 ) => ($(
1092 impl_binop_unsafe! {@inner
1093 $kw
1094 op_assign
1095 $t1, $cast {$t2}, $out
1096
1097 $op {$meth}
1098 $op_assign {$meth_assign}
1099 $assign_op {$assign_meth}
1100 $func;
1101 })+
1102
1103 impl_binop_unsafe! {
1104 $kw
1105 op_assign
1106 $t1, $cast {$($t2)+}, $out
1107 $($next)*
1108 }
1109 );
1110 (@inner
1111 $kw:ident
1112 op_assign
1113 $t1:ident, $cast:ty {$t2:ident}, $out:ident
1114 $(
1115 $op:ident {$meth:ident}
1116 $op_assign:ident {$meth_assign:ident}
1117 $assign_op:ident {$assign_meth:ident}
1118 $func:path;
1119 )*
1120 ) => ($(
1121 impl_binop! {
1122 op_assign
1123 $t1, $t2, $out
1124 $op {$meth}
1125 {
1126 fn $meth(self, rhs: &$t2) -> $out {
1127 let mut res = default!($op, $kw, $out, self, rhs);
1128 call_unsafe!(cast_rhs $kw, $func, $cast, res, self, rhs);
1129 res
1130 }
1131 }
1132 $op_assign {$meth_assign}
1133 {
1134 fn $meth_assign(&mut self, rhs: &$t2) {
1135 call_unsafe!(cast_rhs $kw, $func, $cast, self, self, rhs);
1136 }
1137 }
1138 $assign_op {$assign_meth}
1139 {
1140 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1141 call_unsafe!(cast_rhs $kw, $func, $cast, self, lhs, rhs);
1142 }
1143 }
1144 }
1145 )*);
1146 (
1147 $kw:ident
1148 op_assign
1149 $t1:ident, $cast:ty {$($t2:ident)+}, $out:ident
1150 ) => {};
1151 (
1152 $kw:ident
1154 op_from
1155 $t1:ident, $t2:ident, $out:ident
1156 $(
1157 $op:ident {$meth:ident}
1158 $op_from:ident {$meth_from:ident}
1159 $assign_op:ident {$assign_meth:ident}
1160 $func:path;
1161 )+
1162 ) => ($(
1163 impl_binop! {
1164 op_from
1165 $t1, $t2, $out
1166 $op {$meth}
1167 {
1168 fn $meth(self, rhs: &$t2) -> $out {
1169 let mut res = default!($op, $kw, $out, self, rhs);
1170 call_unsafe!($kw, $func, res, self, rhs);
1171 res
1172 }
1173 }
1174 $op_from {$meth_from}
1175 {
1176 fn $meth_from(&mut self, lhs: &$t1) {
1177 call_unsafe!($kw, $func, self, lhs, self);
1178 }
1179 }
1180 $assign_op {$assign_meth}
1181 {
1182 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1183 call_unsafe!($kw, $func, self, lhs, rhs);
1184 }
1185 }
1186 }
1187 )+);
1188 (
1189 $kw:ident
1191 op_from
1192 $cast:ty {$($t1:ident)+}, $t2:ident, $out:ident
1193
1194 $op:ident {$meth:ident}
1195 $op_from:ident {$meth_from:ident}
1196 $assign_op:ident {$assign_meth:ident}
1197 $func:path;
1198
1199 $($next:tt)*
1200 ) => ($(
1201 impl_binop_unsafe! {@inner
1202 $kw
1203 op_from
1204 $cast {$t1}, $t2, $out
1205
1206 $op {$meth}
1207 $op_from {$meth_from}
1208 $assign_op {$assign_meth}
1209 $func;
1210 })+
1211
1212 impl_binop_unsafe! {
1213 $kw
1214 op_from
1215 $cast {$($t1)+}, $t2, $out
1216 $($next)*
1217 }
1218 );
1219 (@inner
1220 $kw:ident
1221 op_from
1222 $cast:ty {$t1:ident}, $t2:ident, $out:ident
1223 $(
1224 $op:ident {$meth:ident}
1225 $op_from:ident {$meth_from:ident}
1226 $assign_op:ident {$assign_meth:ident}
1227 $func:path;
1228 )*
1229 ) => ($(
1230 impl_binop! {
1231 op_from
1232 $t1, $t2, $out
1233 $op {$meth}
1234 {
1235 fn $meth(self, rhs: &$t2) -> $out {
1236 let mut res = default!($op, $kw, $out, self, rhs);
1237 call_unsafe!(cast_lhs $kw, $func, $cast, res, self, rhs);
1238 res
1239 }
1240 }
1241 $op_from {$meth_from}
1242 {
1243 fn $meth_from(&mut self, lhs: &$t1) {
1244 call_unsafe!(cast_lhs $kw, $func, $cast, self, lhs, self);
1245 }
1246 }
1247 $assign_op {$assign_meth}
1248 {
1249 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1250 call_unsafe!(cast_lhs $kw, $func, $cast, self, lhs, rhs);
1251 }
1252 }
1253 }
1254 )*);
1255 (
1256 $kw:ident
1257 op_from
1258 $cast:ty {$($t1:ident)+}, $t2:ident, $out:ident
1259 ) => {};
1260 (
1261 $kw:ident
1263 $t1:ident, $t2:ident, $out:ident
1264 $(
1265 $op:ident {$meth:ident}
1266 $assign_op:ident {$assign_meth:ident}
1267 $func:path;
1268 )+
1269 ) => ($(
1270 impl_binop! {
1271 $t1, $t2, $out
1272 $op {$meth}
1273 {
1274 fn $meth(self, rhs: &$t2) -> $out {
1275 let mut res = default!($op, $kw, $out, self, rhs);
1276 call_unsafe!($kw, $func, res, self, rhs);
1277 res
1278 }
1279 }
1280 $assign_op {$assign_meth}
1281 {
1282 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1283 call_unsafe!($kw, $func, self, lhs, rhs);
1284 }
1285 }
1286 }
1287 )+);
1288 (
1289 $kw:ident
1291 $cast:ty {$($t1:ident)+}, $t2:ident, $out:ident
1292
1293 $op:ident {$meth:ident}
1294 $assign_op:ident {$assign_meth:ident}
1295 $func:path;
1296
1297 $($next:tt)*
1298 ) => ($(
1299 impl_binop_unsafe! {@inner
1300 $kw
1301 $cast {$t1}, $t2, $out
1302
1303 $op {$meth}
1304 $assign_op {$assign_meth}
1305 $func;
1306 })+
1307
1308 impl_binop_unsafe! {
1309 $kw
1310 $cast {$($t1)+}, $t2, $out
1311 $($next)*
1312 }
1313 );
1314 (@inner
1315 $kw:ident
1316 $cast:ty {$t1:ident}, $t2:ident, $out:ident
1317 $(
1318 $op:ident {$meth:ident}
1319 $assign_op:ident {$assign_meth:ident}
1320 $func:path;
1321 )*
1322 ) => ($(
1323 impl_binop! {
1324 $t1, $t2, $out
1325 $op {$meth}
1326 {
1327 fn $meth(self, rhs: &$t2) -> $out {
1328 let mut res = default!($op, $kw, $out, self, rhs);
1329 call_unsafe!(cast_lhs $kw, $func, $cast, res, self, rhs);
1330 res
1331 }
1332 }
1333 $assign_op {$assign_meth}
1334 {
1335 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1336 call_unsafe!(cast_lhs $kw, $func, $cast, self, lhs, rhs);
1337 }
1338 }
1339 }
1340 )*);
1341 (
1342 $kw:ident
1343 $cast:ty {$($t1:ident)+}, $t2:ident, $out:ident
1344 ) => {};
1345 (
1346 $kw:ident
1348 $t1:ident, $cast:ty {$($t2:ident)+}, $out:ident
1349
1350 $op:ident {$meth:ident}
1351 $assign_op:ident {$assign_meth:ident}
1352 $func:path;
1353
1354 $($next:tt)*
1355 ) => ($(
1356 impl_binop_unsafe! {@inner
1357 $kw
1358 $t1, $cast {$t2}, $out
1359
1360 $op {$meth}
1361 $assign_op {$assign_meth}
1362 $func;
1363 })+
1364
1365 impl_binop_unsafe! {
1366 $kw
1367 $t1, $cast {$($t2)+}, $out
1368 $($next)*
1369 }
1370 );
1371 (@inner
1372 $kw:ident
1373 $t1:ident, $cast:ty {$t2:ident}, $out:ident
1374 $(
1375 $op:ident {$meth:ident}
1376 $assign_op:ident {$assign_meth:ident}
1377 $func:path;
1378 )*
1379 ) => ($(
1380 impl_binop! {
1381 $t1, $t2, $out
1382 $op {$meth}
1383 {
1384 fn $meth(self, rhs: &$t2) -> $out {
1385 let mut res = default!($op, $kw, $out, self, rhs);
1386 call_unsafe!(cast_rhs $kw, $func, $cast, res, self, rhs);
1387 res
1388 }
1389 }
1390 $assign_op {$assign_meth}
1391 {
1392 fn $assign_meth(&mut self, lhs: &$t1, rhs: &$t2) {
1393 call_unsafe!(cast_rhs $kw, $func, $cast, self, lhs, rhs);
1394 }
1395 }
1396 }
1397 )*);
1398 (
1399 $kw:ident
1400 $t1:ident, $cast:ty {$($t2:ident)+}, $out:ident
1401 ) => {};
1402}
1403
1404#[macro_export]
1406macro_rules! impl_from {
1407 (
1408 $t1:ident, $t2:ident
1409 {
1410 $($code:tt)*
1411 }
1412 ) => {
1413 impl From<$t2> for $t1 {
1414 #[inline]
1415 fn from(src: $t2) -> $t1 {
1416 <$t1>::from(&src)
1417 }
1418 }
1419
1420 impl From<&$t2> for $t1 {
1421 #[inline]
1422 $($code)*
1423 }
1424 };
1425}
1426
1427macro_rules! impl_from_unsafe {
1429 (
1430 $kw:ident
1431 $t1:ident, $t2:ident
1432 $func:path
1433 ) => (
1434 impl_from! {
1435 $t1, $t2
1436 {
1437 fn from(src: &$t2) -> $t1 {
1438 let mut res = default!(From, $kw, $t1, src);
1439 call_unsafe!($kw, $func, res, src);
1440 res
1441 }
1442 }
1443 }
1444 );
1445 (
1446 $kw:ident
1448 $t1:ident, $cast:ident {$($t2:ident)*}
1449 $func:path
1450 ) => ($(
1451 impl_from! {
1452 $t1, $t2
1453 {
1454 fn from(src: &$t2) -> $t1 {
1455 let mut res = default!(From, $kw, $t1, src);
1456 call_unsafe!(cast $kw, $func, $cast, res, src);
1457 res
1458 }
1459 }
1460 }
1461 )*);
1462 }
1482
1483#[macro_export]
1485macro_rules! impl_tryfrom {
1486 (
1487 $t1:ident, $t2:ident
1488 {
1489 $($code:tt)*
1490 }
1491 ) => {
1492 impl TryFrom<$t2> for $t1 {
1493 type Error = &'static str;
1494 #[inline]
1495 fn try_from(src: $t2) -> Result<Self,Self::Error> {
1496 <$t1>::try_from(&src)
1497 }
1498 }
1499
1500 impl TryFrom<&$t2> for $t1 {
1501 type Error = &'static str;
1502 #[inline]
1503 $($code)*
1504 }
1505 };
1506}
1507
1508macro_rules! impl_tryfrom_unsafe {
1510 (
1511 $kw:ident
1512 $t1:ident, $t2:ident
1513 $func:path
1514 ) => (
1515 impl_tryfrom! {
1516 $t1, $t2
1517 {
1518 fn from(src: &$t2) -> $t1 {
1519 let mut res = default!(From, $kw, $t1, src);
1520 call_unsafe!($kw, $func, res, src);
1521 res
1522 }
1523 }
1524 }
1525 );
1526 (
1527 $kw:ident
1529 $t1:ident, $cast:ident {$($t2:ident)*}
1530 $func:path
1531 ) => ($(
1532 impl_tryfrom! {
1533 $t1, $t2
1534 {
1535 fn from(src: &$t2) -> $t1 {
1536 let mut res = default!(From, $kw, $t1, src);
1537 call_unsafe!(cast $kw, $func, $cast, res, src);
1538 res
1539 }
1540 }
1541 }
1542 )*);
1543}
1544
1545#[macro_export]
1547macro_rules! impl_assign {
1548 (
1549 $t1:ident, $t2:ident
1550 {
1551 $($code:tt)*
1552 }
1553 ) => {
1554 impl Assign<$t2> for $t1 {
1555 #[inline]
1556 fn assign(&mut self, src: $t2) {
1557 self.assign(&src);
1558 }
1559 }
1560
1561 impl Assign<&$t2> for $t1 {
1562 #[inline]
1563 $($code)*
1564 }
1565 };
1566}
1567
1568macro_rules! impl_assign_unsafe {
1569 (
1570 $kw:ident
1571 $t1:ident, $t2:ident
1572 $func:path
1573 ) => (
1574 impl_assign! {
1575 $t1, $t2
1576 {
1577 fn assign(&mut self, src: &$t2) {
1578 call_unsafe!($kw, $func, self, src);
1579 }
1580 }
1581 }
1582 );
1583 (
1584 $kw:ident
1586 $t1:ident, $cast:ident {$($t2:ident)*}
1587 $func:path
1588 ) => ($(
1589 impl_assign! {
1590 $t1, $t2
1591 {
1592 fn assign(&mut self, src: &$t2) {
1593 call_unsafe!(cast $kw, $func, $cast, self, src);
1594 }
1595 }
1596 }
1597 )*);
1598}
1599