1#!./perl 2 3use strict; 4use warnings; 5 6use Test::More tests => 18; 7 8use Config; 9use List::Util qw(sum); 10 11my $v = sum; 12is( $v, undef, 'no args'); 13 14$v = sum(9); 15is( $v, 9, 'one arg'); 16 17$v = sum(1,2,3,4); 18is( $v, 10, '4 args'); 19 20$v = sum(-1); 21is( $v, -1, 'one -1'); 22 23my $x = -3; 24 25$v = sum($x, 3); 26is( $v, 0, 'variable arg'); 27 28$v = sum(-3.5,3); 29is( $v, -0.5, 'real numbers'); 30 31$v = sum(3,-3.5); 32is( $v, -0.5, 'initial integer, then real'); 33 34my $one = Foo->new(1); 35my $two = Foo->new(2); 36my $thr = Foo->new(3); 37 38$v = sum($one,$two,$thr); 39is($v, 6, 'overload'); 40 41 42{ package Foo; 43 44use overload 45 '""' => sub { ${$_[0]} }, 46 '0+' => sub { ${$_[0]} }, 47 fallback => 1; 48 sub new { 49 my $class = shift; 50 my $value = shift; 51 bless \$value, $class; 52 } 53} 54 55use Math::BigInt; 56my $v1 = Math::BigInt->new(2) ** Math::BigInt->new(65); 57my $v2 = $v1 - 1; 58$v = sum($v1,$v2); 59is($v, $v1 + $v2, 'bigint'); 60 61$v = sum(42, $v1); 62is($v, $v1 + 42, 'bigint + builtin int'); 63 64$v = sum(42, $v1, 2); 65is($v, $v1 + 42 + 2, 'bigint + builtin int'); 66 67{ package example; 68 69 use overload 70 '0+' => sub { $_[0][0] }, 71 '""' => sub { my $r = "$_[0][0]"; $r = "+$r" unless $r =~ m/^\-/; $r .= " [$_[0][1]]"; $r }, 72 fallback => 1; 73 74 sub new { 75 my $class = shift; 76 77 my $this = bless [@_], $class; 78 79 return $this; 80 } 81} 82 83{ 84 my $e1 = example->new(7, "test"); 85 my $t = sum($e1, 7, 7); 86 is($t, 21, 'overload returning non-overload'); 87 $t = sum(8, $e1, 8); 88 is($t, 23, 'overload returning non-overload'); 89 $t = sum(9, 9, $e1); 90 is($t, 25, 'overload returning non-overload'); 91} 92 93SKIP: { 94 skip "IV is not at least 64bit", 4 unless $Config{ivsize} >= 8; 95 96 # Sum using NV will only preserve 53 bits of integer precision 97 my $t = sum(1152921504606846976, 1); # 1<<60, but Perl 5.6 does not compute constant correctly 98 cmp_ok($t, 'gt', 1152921504606846976, 'sum uses IV where it can'); # string comparison because Perl 5.6 does not compare it numerically correctly 99 100 SKIP: { 101 skip "known to fail on $]", 1 if $] le "5.006002"; 102 $t = sum(1<<60, 1); 103 cmp_ok($t, '>', 1<<60, 'sum uses IV where it can'); 104 } 105 106 my $min = -(1<<63); 107 my $max = 9223372036854775807; # (1<<63)-1, but Perl 5.6 does not compute constant correctly 108 109 $t = sum($min, $max); 110 is($t, -1, 'min + max'); 111 $t = sum($max, $min); 112 is($t, -1, 'max + min'); 113} 114