if( $user->permits( FOO ) )
####
if( $user->permits( FOO | BAR | BAZ ) )
####
package User;
...
use constant FOO => 1 << 1;
use constant BAR => 1 << 2;
use constnat BAZ => 1 << 3;
...
sub permits {
my ($self, $mask) = @_;
return ($self->{perms} & $mask);
}
####
package FriedoBits;
use strict;
use overload '|' => \&bitor;
use overload '&' => \&bitand;
sub bitor {
my ($a, $b) = @_;
my $new = [ ];
for(0..3) {
$new->[$_] = ( $a->[$_] | $b->[$_] );
}
return __PACKAGE__->new( $new );
}
sub bitand {
my ($a, $b) = @_;
my $new = [ ];
for(0..3) {
$new->[$_] = ( $a->[$_] & $b->[$_] );
}
return __PACKAGE__->new( $new );
}
sub new {
return bless $_[1], ref($_[0]) || $_[0];
}
use constant PERM_0000 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000001 ] );
use constant PERM_0001 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000002 ] );
use constant PERM_0002 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000004 ] );
use constant PERM_0003 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000008 ] );
use constant PERM_0004 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000010 ] );
use constant PERM_0005 => FriedoBits->new(
[ 0x00000000, 0x00000000, 0x00000000, 0x00000020 ] );
...
use constant PERM_0125 => FriedoBits->new(
[ 0x20000000, 0x00000000, 0x00000000, 0x00000000 ] );
use constant PERM_0126 => FriedoBits->new(
[ 0x40000000, 0x00000000, 0x00000000, 0x00000000 ] );
use constant PERM_0127 => FriedoBits->new(
[ 0x80000000, 0x00000000, 0x00000000, 0x00000000 ] );
1;
####
Benchmark: timing 100000 iterations of BigInt...
BigInt: 188 wallclock secs
(168.07 usr + 0.36 sys = 168.43 CPU) @ 593.72/s (n=100000)
Benchmark: timing 100000 iterations of BigIntGMP...
BigIntGMP: 44 wallclock secs
(38.50 usr + 0.13 sys = 38.63 CPU) @ 2588.66/s (n=100000)
Benchmark: timing 100000 iterations of FriedoBits...
FriedoBits: 3 wallclock secs ( 3.11 usr + 0.01 sys = 3.12 CPU) @ 32051.28/s (n=100000)