1#![no_std]
14
15#![cfg_attr(feature = "debug-trace-macros", feature(trace_macros))]
16#[cfg(feature = "debug-trace-macros")] trace_macros!(true);
17
18#[macro_export(local_inner_macros)]
172macro_rules! newtype_ops {
173 ($($rest:tt)*) => { newtype_ops__!{ @product::next($($rest)*) -> () }};
174}
175
176#[macro_export(local_inner_macros)]
177#[doc(hidden)]
178macro_rules! newtype_ops__ {
179
180 (@product::next({$($token:tt)+} $($rest:tt)*) -> $args:tt) => {
184 newtype_ops__!{ @product::unpack({$($token)+} $($rest)*) -> $args }};
185 (@product::next( $token:tt $($rest:tt)*) -> $args:tt) => {
186 newtype_ops__!{ @product::single($token $($rest)*) -> $args }};
187 (@product::next() -> $args:tt) => {
188 newtype_ops__!{ @interpret$args }};
189
190 (@product::single($token:tt $($rest:tt)*) -> ($($args:tt)*)) => {
192 newtype_ops__!{ @product::next($($rest)*) -> ($($args)* $token) }};
193
194 (@product::unpack({$($token:tt)*} $($rest:tt)*) -> $args:tt) => {
198 newtype_ops__!{ @product::unpack_2({$($token)*} [$($rest)*]) -> $args }};
199 (@product::unpack_2({$($token:tt)*} $rest:tt) -> $args:tt) => {
201 $( newtype_ops__!{ @product::unpack_3($token $rest) -> $args } )* };
202 (@product::unpack_3($token:tt [$($rest:tt)*]) -> $args:tt) => {
206 newtype_ops__!{ @product::single($token $($rest)*) -> $args }};
207
208 (@interpret($($rest:tt)*)) => { newtype_ops__!{ @interpret::type($($rest)*) -> () }};
212
213 (@interpret::type([$($T:tt)*] $($rest:tt)*) -> ($($args:tt)*)) => {
214 newtype_ops__!{ @interpret::oper($($rest)*) -> ($($args)* {value_ty:[$($T)*]}) }};
215
216 (@interpret::oper(arithmetic $($rest:tt)*) -> ($($args:tt)*)) => {
217 newtype_ops__!{ @interpret::oper(add $($rest)*) -> ($($args)*) }
218 newtype_ops__!{ @interpret::oper(sub $($rest)*) -> ($($args)*) }
219 newtype_ops__!{ @interpret::oper(mul $($rest)*) -> ($($args)*) }
220 newtype_ops__!{ @interpret::oper(div $($rest)*) -> ($($args)*) }
221 newtype_ops__!{ @interpret::oper(rem $($rest)*) -> ($($args)*) }
222 newtype_ops__!{ @interpret::oper(neg $($rest)*) -> ($($args)*) }
223 };
224
225 (@interpret::oper(integer $($rest:tt)*) -> ($($args:tt)*)) => {
230 newtype_ops__!{ @interpret::oper(bitand $($rest)*) -> ($($args)*) }
231 newtype_ops__!{ @interpret::oper(bitor $($rest)*) -> ($($args)*) }
232 newtype_ops__!{ @interpret::oper(bitxor $($rest)*) -> ($($args)*) }
233 newtype_ops__!{ @interpret::oper(not $($rest)*) -> ($($args)*) }
234 newtype_ops__!{ @interpret::oper(add $($rest)*) -> ($($args)*) }
235 newtype_ops__!{ @interpret::oper(sub $($rest)*) -> ($($args)*) }
236 newtype_ops__!{ @interpret::oper(mul $($rest)*) -> ($($args)*) }
237 newtype_ops__!{ @interpret::oper(div $($rest)*) -> ($($args)*) }
238 newtype_ops__!{ @interpret::oper(rem $($rest)*) -> ($($args)*) }
239 newtype_ops__!{ @interpret::oper(neg $($rest)*) -> ($($args)*) }
240 };
241
242 (@interpret::oper(arith_ring $($rest:tt)*) -> ($($args:tt)*)) => {
243 newtype_ops__!{ @interpret::oper(add $($rest)*) -> ($($args)*) }
244 newtype_ops__!{ @interpret::oper(sub $($rest)*) -> ($($args)*) }
245 newtype_ops__!{ @interpret::oper(mul $($rest)*) -> ($($args)*) }
246 newtype_ops__!{ @interpret::oper(neg $($rest)*) -> ($($args)*) }
247 };
248
249 (@interpret::oper(bitwise $($rest:tt)*) -> ($($args:tt)*)) => {
250 newtype_ops__!{ @interpret::oper(bitand $($rest)*) -> ($($args)*) }
251 newtype_ops__!{ @interpret::oper(bitor $($rest)*) -> ($($args)*) }
252 newtype_ops__!{ @interpret::oper(bitxor $($rest)*) -> ($($args)*) }
253 newtype_ops__!{ @interpret::oper(not $($rest)*) -> ($($args)*) }
254 };
255
256 (@interpret::oper(add $($rest:tt)*) -> ($($args:tt)*)) => {
263 newtype_ops__!{ @interpret::mode($($rest)*) -> (
264 $($args)* {kind:binary}
265 {traits:[[::core::ops::Add][::core::ops::AddAssign]]}
266 {methods:[[add][add_assign]]}
267 )}};
268
269 (@interpret::oper(sub $($rest:tt)*) -> ($($args:tt)*)) => {
270 newtype_ops__!{ @interpret::mode($($rest)*) -> (
271 $($args)* {kind:binary}
272 {traits:[[::core::ops::Sub][::core::ops::SubAssign]]}
273 {methods:[[sub][sub_assign]]}
274 )}};
275
276 (@interpret::oper(mul $($rest:tt)*) -> ($($args:tt)*)) => {
277 newtype_ops__!{ @interpret::mode($($rest)*) -> (
278 $($args)* {kind:binary}
279 {traits:[[::core::ops::Mul][::core::ops::MulAssign]]}
280 {methods:[[mul][mul_assign]]}
281 )}};
282
283 (@interpret::oper(div $($rest:tt)*) -> ($($args:tt)*)) => {
284 newtype_ops__!{ @interpret::mode($($rest)*) -> (
285 $($args)* {kind:binary}
286 {traits:[[::core::ops::Div][::core::ops::DivAssign]]}
287 {methods:[[div][div_assign]]}
288 )}};
289
290 (@interpret::oper(rem $($rest:tt)*) -> ($($args:tt)*)) => {
291 newtype_ops__!{ @interpret::mode($($rest)*) -> (
292 $($args)* {kind:binary}
293 {traits:[[::core::ops::Rem][::core::ops::RemAssign]]}
294 {methods:[[rem][rem_assign]]}
295 )}};
296
297 (@interpret::oper(neg $($rest:tt)*) -> ($($args:tt)*)) => {
298 newtype_ops__!{ @interpret::mode($($rest)*) -> (
299 $($args)* {kind:unary}
300 {traits:[[::core::ops::Neg]]}
301 {methods:[[neg]]}
302 )}};
303
304 (@interpret::oper(bitand $($rest:tt)*) -> ($($args:tt)*)) => {
305 newtype_ops__!{ @interpret::mode($($rest)*) -> (
306 $($args)* {kind:binary}
307 {traits:[[::core::ops::BitAnd][::core::ops::BitAndAssign]]}
308 {methods:[[bitand][bitand_assign]]}
309 )}};
310
311 (@interpret::oper(bitor $($rest:tt)*) -> ($($args:tt)*)) => {
312 newtype_ops__!{ @interpret::mode($($rest)*) -> (
313 $($args)* {kind:binary}
314 {traits:[[::core::ops::BitOr][::core::ops::BitOrAssign]]}
315 {methods:[[bitor][bitor_assign]]}
316 )}};
317
318 (@interpret::oper(bitxor $($rest:tt)*) -> ($($args:tt)*)) => {
319 newtype_ops__!{ @interpret::mode($($rest)*) -> (
320 $($args)* {kind:binary}
321 {traits:[[::core::ops::BitXor][::core::ops::BitXorAssign]]}
322 {methods:[[bitxor][bitxor_assign]]}
323 )}};
324
325 (@interpret::oper(not $($rest:tt)*) -> ($($args:tt)*)) => {
326 newtype_ops__!{ @interpret::mode($($rest)*) -> (
327 $($args)* {kind:unary}
328 {traits:[[::core::ops::Not]]}
329 {methods:[[not]]}
330 )}};
331
332 (@interpret::mode(normal $($rest:tt)*) -> ($($args:tt)*)) => {
334 newtype_ops__!{ @interpret::self($($rest)*) -> ($($args)* {mode:normal}) }};
335 (@interpret::mode(assign $($rest:tt)*) -> ($($args:tt)*)) => {
336 newtype_ops__!{ @interpret::self($($rest)*) -> ($($args)* {mode:assign}) }};
337 (@interpret::mode(: $($rest:tt)*) -> ($($args:tt)*)) => {
338 newtype_ops__!{ @interpret::self($($rest)*) -> ($($args)* {mode:normal}) }};
339 (@interpret::mode(= $($rest:tt)*) -> ($($args:tt)*)) => {
340 newtype_ops__!{ @interpret::self($($rest)*) -> ($($args)* {mode:assign}) }};
341
342 (@interpret::self(&Self $($rest:tt)*) -> ($($args:tt)*)) => {
343 newtype_ops__!{ @interpret::other($($rest)*) -> ($($args)* {recv_form:[&x.0]}) }};
344 (@interpret::self(^Self $($rest:tt)*) -> ($($args:tt)*)) => {
345 newtype_ops__!{ @interpret::other($($rest)*) -> ($($args)* {recv_form:[x.0]}) }};
346 (@interpret::self(Self $($rest:tt)*) -> ($($args:tt)*)) => {
347 newtype_ops__!{ @interpret::other($($rest)*) -> ($($args)* {recv_form:[x.0]}) }};
348
349 (@interpret::other(&Self) -> ($($args:tt)*)) => {
359 newtype_ops__!{ @postprocess($($args)* {arg:[#ref]} {arg_form:[&x.0]}) }};
360 (@interpret::other(^Self) -> ($($args:tt)*)) => {
361 newtype_ops__!{ @postprocess($($args)* {arg:[#value]} {arg_form:[x.0]}) }};
362 (@interpret::other(Self) -> ($($args:tt)*)) => {
363 newtype_ops__!{ @postprocess($($args)* {arg:[#value]} {arg_form:[x.0]}) }};
364 (@interpret::other() -> ($($args:tt)*)) => {
365 newtype_ops__!{ @postprocess($($args)* {arg:[#value]} {arg_form:[x.0]}) }};
366 (@interpret::other(^$($rest:tt)+) -> ($($args:tt)*)) => {
368 newtype_ops__!{ @postprocess($($args)* {arg:[$($rest)*]} {arg_form:[x]}) }};
369 (@interpret::other($($rest:tt)+) -> ($($args:tt)*)) => {
370 newtype_ops__!{ @postprocess($($args)* {arg:[$($rest)*]} {arg_form:[x]}) }};
371
372 (@postprocess(
376 $value_ty:tt $kind:tt $traits:tt $methods:tt $mode:tt $recv_form:tt $arg:tt $arg_form:tt
377 )) => {
378 newtype_ops__!{ @postprocess::blacklist(
379 [$mode $kind $recv_form $arg_form $arg] [$arg $value_ty $recv_form] $traits $methods $recv_form $arg_form ) }
383 };
384
385 (@postprocess::blacklist([{mode:assign} {kind:unary} $($more:tt)*] $($rest:tt)*)) => {
395 };
396 (@postprocess::blacklist([{mode:assign} {kind:binary} $($more:tt)*] $($rest:tt)*)) => {
397 newtype_ops__!{ @postprocess::blacklist([{kind:assign} $($more)*] $($rest)*) }};
398 (@postprocess::blacklist([{mode:normal} {kind:unary} $($more:tt)*] $($rest:tt)*)) => {
399 newtype_ops__!{ @postprocess::blacklist([{kind:unary} $($more)*] $($rest)*) }};
400 (@postprocess::blacklist([{mode:normal} {kind:binary} $($more:tt)*] $($rest:tt)*)) => {
401 newtype_ops__!{ @postprocess::blacklist([{kind:binary} $($more)*] $($rest)*) }};
402
403 (@postprocess::blacklist([{kind:assign} {recv_form:[&x.0]} $arg_form:tt $arg:tt] $($rest:tt)*)) => { };
405 (@postprocess::blacklist([{kind:unary} $recv_form:tt {arg_form:[&x.0]} $arg:tt] $($rest:tt)*)) => { };
407 (@postprocess::blacklist([{kind:unary} $recv_form:tt {arg_form:[x]} $arg:tt] $($rest:tt)*)) => { };
408
409 (@postprocess::blacklist([{kind:assign} $recv_form:tt $arg_form:tt {arg:[#ref]}] $($rest:tt)*)) => { };
416 (@postprocess::blacklist([{kind:assign} $recv_form:tt $arg_form:tt {arg:[&$($arg:tt)+]}] $($rest:tt)*)) => { };
417
418 (@postprocess::blacklist([{kind:$kind:tt} $($dropped:tt)*] $($rest:tt)*)) => {
419 newtype_ops__!{ @postprocess::true_types($($rest)* {kind: $kind}) }};
420
421 (@postprocess::true_types(
423 [{arg:[#value]} {value_ty:[$($T:tt)*]} $recv_form:tt] $($rest:tt)*
424 )) => { newtype_ops__!{ @postprocess::true_types::2(
425 [{value_ty:[$($T)*]} $recv_form {arg:[$($T)*]}] $($rest)*
426 )}};
427 (@postprocess::true_types(
428 [{arg:[#ref]} {value_ty:[$($T:tt)*]} $recv_form:tt] $($rest:tt)*
429 )) => { newtype_ops__!{ @postprocess::true_types::2(
430 [{value_ty:[$($T)*]} $recv_form {arg:[&$($T)*]}] $($rest)*
431 )}};
432 (@postprocess::true_types(
433 [{arg:[$($arg:tt)*]} {value_ty:[$($T:tt)*]} $recv_form:tt] $($rest:tt)*
434 )) => { newtype_ops__!{ @postprocess::true_types::2(
435 [{value_ty:[$($T)*]} $recv_form {arg:[$($arg)*]}] $($rest)*
436 )}};
437
438 (@postprocess::true_types::2(
440 [{value_ty:[$($T:tt)*]} {recv_form:[&$($recv_form:tt)*]} {arg:[&$($arg:tt)*]}] $($rest:tt)*
441 )) => {
442 newtype_ops__!{ @postprocess::almost_there(
443 $($rest)* {tpars:[<'a,'b>]} {recv:[&'a $($T)*]} {arg:[&'b $($arg)*]} {out:[$($T)*]}
444 )}
445 };
446
447 (@postprocess::true_types::2(
448 [{value_ty:[$($T:tt)*]} {recv_form:[&$($recv_form:tt)*]} {arg:[$($arg:tt)*]}] $($rest:tt)*
449 )) => {
450 newtype_ops__!{ @postprocess::almost_there(
451 $($rest)* {tpars:[<'a>]} {recv:[&'a $($T)*]} {arg:[$($arg)*]} {out:[$($T)*]}
452 )}
453 };
454
455 (@postprocess::true_types::2(
456 [{value_ty:[$($T:tt)*]} {recv_form:[$($recv_form:tt)*]} {arg:[&$($arg:tt)*]}] $($rest:tt)*
457 )) => {
458 newtype_ops__!{ @postprocess::almost_there(
459 $($rest)* {tpars:[<'b>]} {recv:[$($T)*]} {arg:[&'b $($arg)*]} {out:[$($T)*]}
460 )}
461 };
462
463 (@postprocess::true_types::2(
464 [{value_ty:[$($T:tt)*]} {recv_form:[$($recv_form:tt)*]} {arg:[$($arg:tt)*]}] $($rest:tt)*
465 )) => {
466 newtype_ops__!{ @postprocess::almost_there(
467 $($rest)* {tpars:[]} {recv:[$($T)*]} {arg:[$($arg)*]} {out:[$($T)*]}
468 )}
469 };
470
471 (@postprocess::almost_there(
474 {traits:$traits:tt} {methods:$methods:tt}
475 {recv_form:$recv_form:tt} {arg_form:$arg_form:tt}
476 {kind:$kind:tt} {tpars:$tpars:tt} {recv:$Recv:tt} {arg:$Arg:tt} {out:$Out:tt} )) => {
479 newtype_ops__!{
480 @impl::$kind
481 traits:$traits methods:$methods
482 tpars:$tpars recv:$Recv arg:$Arg out:$Out
483 forms:[$recv_form $arg_form]
484 }
485 };
486
487 (@impl::unary
488 traits:[[$($Trait:tt)*]]
489 methods:[[$meth:ident]]
490 tpars:[$($tpars:tt)*] recv:[$Recv:ty] arg:$_Arg:tt out:[$Out:path]
491 forms:[[$($form1:tt)*] $_form2:tt]
492 ) => {
493 impl$($tpars)* $($Trait)* for $Recv {
494 type Output = $Out;
495 fn $meth(self) -> $Out {
496 let this = self;
497 $Out(
498 newtype_ops__!(@helper::delegate [$($form1)*] [this] [0]).$meth()
499 )
500 }
501 }
502 };
503
504 (@impl::binary
505 traits:[[$($Trait:tt)*] $_TraitAssign:tt]
506 methods:[[$meth:ident] $_meth_assign:tt]
507 tpars:[$($tpars:tt)*] recv:[$Recv:ty] arg:[$Arg:ty] out:[$Out:path]
508 forms:[[$($form1:tt)*][$($form2:tt)*]]
509 ) => {
510 impl$($tpars)* $($Trait)*<$Arg> for $Recv {
511 type Output = $Out;
512 fn $meth(self, other: $Arg) -> $Out {
513 let this = self;
514 $Out(
515 newtype_ops__!(@helper::delegate [$($form1)*] [this] [0])
516 .$meth(
517 newtype_ops__!(@helper::delegate [$($form2)*] [other] [0])
518 )
519 )
520 }
521 }
522 };
523
524 (@impl::assign
525 traits:[$_Trait:tt [$($TraitAssign:tt)*]]
526 methods:[$_meth:tt [$meth_assign:ident]]
527 tpars:[$($tpars:tt)*] recv:[$Recv:ty] arg:[$Arg:ty] out:$_Out:tt
528 forms:[$_form1:tt [$($form2:tt)*]]
529 ) => {
530 impl$($tpars)* $($TraitAssign)*<$Arg> for $Recv {
531 fn $meth_assign(&mut self, other: $Arg) {
532 let this = self;
533 newtype_ops__!(@helper::delegate [&mut x.0] [this] [0])
534 .$meth_assign(
535 newtype_ops__!(@helper::delegate [$($form2)*] [other] [0])
536 )
537 }
538 }
539 };
540
541 (@helper::delegate [&mut x.0] [$id:ident] [$fld:tt]) => { &mut $id.$fld };
542 (@helper::delegate [&x.0] [$id:ident] [$fld:tt]) => { &$id.$fld };
543 (@helper::delegate [x.0] [$id:ident] [$fld:tt]) => { $id.$fld };
544 (@helper::delegate [x] [$id:ident] [$fld:tt]) => { $id };
545}
546
547#[cfg(test)]
548mod tests {
549
550 mod broad_1 {
556 mod foo {
557 #[derive(Eq,PartialEq,Debug)]
558 pub struct Foo(pub i32);
559 }
560 #[derive(Eq,PartialEq,Debug)]
561 pub struct Bar(pub i32);
562
563 newtype_ops!{ {[foo::Foo][Bar]} integer {:=} {^&}Self {^&}{Self i32} }
564
565 use self::foo::Foo;
566 #[test]
567 fn test() {
568
569 assert_eq!(Foo(5), Foo(2) + Foo(3));
571 assert_eq!(Foo(5), Foo(2) + &Foo(3));
572 assert_eq!(Foo(5), &Foo(2) + Foo(3));
573 assert_eq!(Foo(5), &Foo(2) + &Foo(3));
574
575 assert_eq!(Foo(4), Foo(8) / 2);
576 assert_eq!(Foo(4), &Foo(8) / 2);
577 assert_eq!(Foo(4), Foo(8) / &2);
578 assert_eq!(Foo(4), &Foo(8) / &2);
579
580 assert_eq!(Foo(-3), -Foo(3));
581 assert_eq!(Foo(-3), -&Foo(3));
582
583 assert_eq!(Bar(5), Bar(2) + Bar(3));
585
586 let mut foo = Foo(4);
587 foo += 2;
588 assert_eq!(foo, Foo(6));
589 foo += Foo(2);
590 assert_eq!(foo, Foo(8));
591 }
592 }
593
594 mod proper_forwarding {
598
599 #[derive(Eq,PartialEq,Debug)]
600 pub struct Inner(pub i32);
601 #[derive(Eq,PartialEq,Debug)]
602 pub struct Foo(pub Inner);
603
604 newtype_ops!{ [Inner] {add div neg} {assign normal} {^&}Self {^&}{Self i32} }
605 newtype_ops!{ [Foo] {add div neg} {assign normal} {^&}Self {^&}{Self Inner i32} }
606
607 #[test]
608 fn test() {
609 let foo = |x| Foo(Inner(x));
610
611 assert_eq!(foo(4), foo(8) / foo(2));
613 assert_eq!(foo(4), foo(8) / &foo(2));
614 assert_eq!(foo(4), &foo(8) / foo(2));
615 assert_eq!(foo(4), &foo(8) / &foo(2));
616
617 assert_eq!(foo(4), foo(8) / Inner(2));
618 assert_eq!(foo(4), &foo(8) / Inner(2));
619 assert_eq!(foo(4), foo(8) / &Inner(2));
620 assert_eq!(foo(4), &foo(8) / &Inner(2));
621
622 assert_eq!(foo(4), foo(8) / 2);
623 assert_eq!(foo(4), &foo(8) / 2);
624 assert_eq!(foo(4), foo(8) / &2);
625 assert_eq!(foo(4), &foo(8) / &2);
626
627 assert_eq!(foo(-3), -foo(3));
628 assert_eq!(foo(-3), -&foo(3));
629
630 let mut x = foo(4);
631 x += foo(2);
632 assert_eq!(x, foo(6));
633 x += Inner(2);
634 assert_eq!(x, foo(8));
635 x += 2;
636 assert_eq!(x, foo(10));
637 }
638 }
639
640 mod op_bindings {
643 macro_rules! make_structs {
646 ($($T:ident),*) => {$(
647 #[derive(Eq,PartialEq,Debug,Copy,Clone)]
648 pub struct $T(pub i32);
649 impl From<i32> for $T {
650 fn from(x: i32) -> $T { $T(x) }
651 }
652 )*};
653 }
654 make_structs!{ Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Neg, Not }
656
657 newtype_ops!{ [Add] add {assign normal} Self Self }
658 newtype_ops!{ [Sub] sub {assign normal} Self Self }
659 newtype_ops!{ [Mul] mul {assign normal} Self Self }
660 newtype_ops!{ [Div] div {assign normal} Self Self }
661 newtype_ops!{ [Rem] rem {assign normal} Self Self }
662 newtype_ops!{ [BitAnd] bitand {assign normal} Self Self }
663 newtype_ops!{ [BitOr] bitor {assign normal} Self Self }
664 newtype_ops!{ [BitXor] bitxor {assign normal} Self Self }
665 newtype_ops!{ [Neg] neg {assign normal} Self }
666 newtype_ops!{ [Not] not {assign normal} Self }
667
668 fn run_binary_tests<T,F1,G1,F2,G2>(int_func: F1, foo_func: G1, int_eq: F2, foo_eq: G2)
670 where
671 T: ::core::fmt::Debug + From<i32> + Eq,
672 F1: Fn(i32, i32) -> i32, G1: Fn(T, T) -> T,
673 F2: Fn(&mut i32, i32), G2: Fn(&mut T, T),
674 {
675 for a in 1..10 {
676 for b in 1..10 {
677 let expected: T = int_func(a, b).into();
678 let actual: T = foo_func(a.into(), b.into());
679 assert_eq!(actual, expected, "ouchie");
680
681 let expected: T = { let mut x = a; int_eq(&mut x, b); x }.into();
682 let actual: T = { let mut x = a.into(); foo_eq(&mut x, b.into()); x };
683 assert_eq!(actual, expected, "eihcuo");
684 }
685 }
686 }
687
688 fn run_unary_tests<T,F,G>(int_func: F, foo_func: G)
689 where T: ::core::fmt::Debug + From<i32> + Eq, F: Fn(i32) -> i32, G: Fn(T) -> T
690 {
691 for a in 1..10 {
692 let expected: T = int_func(a).into();
693 let actual: T = foo_func(a.into());
694 assert_eq!(actual, expected, "ouchie");
695 }
696 }
697
698 #[test]
699 fn test() {
700 run_binary_tests::<Add ,_,_,_,_>(|a,b| a + b, |a,b| a + b, |a,b| *a += b, |a,b| *a += b);
701 run_binary_tests::<Sub ,_,_,_,_>(|a,b| a - b, |a,b| a - b, |a,b| *a -= b, |a,b| *a -= b);
702 run_binary_tests::<Mul ,_,_,_,_>(|a,b| a * b, |a,b| a * b, |a,b| *a *= b, |a,b| *a *= b);
703 run_binary_tests::<Div ,_,_,_,_>(|a,b| a / b, |a,b| a / b, |a,b| *a /= b, |a,b| *a /= b);
704 run_binary_tests::<Rem ,_,_,_,_>(|a,b| a % b, |a,b| a % b, |a,b| *a %= b, |a,b| *a %= b);
705 run_binary_tests::<BitAnd,_,_,_,_>(|a,b| a & b, |a,b| a & b, |a,b| *a &= b, |a,b| *a &= b);
706 run_binary_tests::<BitOr ,_,_,_,_>(|a,b| a | b, |a,b| a | b, |a,b| *a |= b, |a,b| *a |= b);
707 run_binary_tests::<BitXor,_,_,_,_>(|a,b| a ^ b, |a,b| a ^ b, |a,b| *a ^= b, |a,b| *a ^= b);
708 run_unary_tests::<Neg,_,_>(|a| -a, |a| -a);
709 run_unary_tests::<Not,_,_>(|a| !a, |a| !a);
710 }
711
712 #[test] #[should_panic(expected = "ouchie")]
714 fn bad_binary() {
715 run_binary_tests::<Add ,_,_,_,_>(|a,b| a * b, |a,b| a + b, |a,b| *a += b, |a,b| *a += b);
716 }
717
718 #[test] #[should_panic(expected = "eihcuo")]
719 fn bad_assign() {
720 run_binary_tests::<Add ,_,_,_,_>(|a,b| a + b, |a,b| a + b, |a,b| *a *= b, |a,b| *a += b);
721 }
722
723 #[test] #[should_panic(expected = "ouchie")]
724 fn bad_unary() {
725 run_unary_tests::<Neg,_,_>(|a| !a, |a| -a);
726 }
727 }
728}