Perl6-Pugs

 view release on metacpan or  search on metacpan

ext/Set-Infinite/lib/Set/Infinite.pm  view on Meta::CPAN

    $res.set = $tmp;
    return $res;
}
method difference ($self: $span ) returns Set::Infinite {
    my $span0 = $self.set;
    my $span1 = $self._normalize_parameter( $span );
    my $tmp = $span1.complement;
    $tmp = $span0.intersection( $tmp );
    my $res = Set::Infinite.new();
    $res.set = $tmp;
    return $res;
}

# mutators

method add ($self: $span ) {
    my $tmp = $self.union( $span );
    $.set = $tmp.set;
}
method remove ($self: $span ) {
    my $tmp = $self.difference( $span );
    $.set = $tmp.set;
}

# scalar methods, iterators

method next ( $x ) { 
    # TODO - simplify this 
    for $.set.spans {
        my $result = $_.next( $x );
        return $result if $result != Inf;
    }
    return Inf;
}

method previous ( $x ) { 
    # TODO - simplify this 
    my @a = $.set.spans;
    @a = reverse @a;
    for @a {
        my $result = $_.previous( $x );
        return $result if $result != -Inf;
    }
    return -Inf;
}

method current ($self: $x ) {
    return $self.next( $self.previous( $x ) );
}

method closest ($self: $x ) {
    my $n = $self.next( $x );
    my $p = $self.current( $x );
    return $n - $x < $x - $p ?? $n !! $p;
}

method iterator ($self: ) returns Set::Infinite::Iterator {
    return ::Set::Infinite::Iterator.new( set => $.set );
}

coro lazy ($self: ) {
    my $iter = $self.iterator();
    loop { 
        my $n = $iter.next;
        return unless defined $n;
        yield $n;
    }
}

} # class Set::Infinite

class Set::Infinite::Iterator
{
    has $.current_span;
    has $.current;
    has $.set;
    submethod BUILD ( $.set ) {}
    method next ($self: ) {
        # TODO - simplify this
        my @spans = $.set.spans;
        loop {
            if defined $.current {
                my $span = @spans[$.current_span];
                $.current = $span.next( $.current );                
            }
            else {
                if defined $.current_span {
                    $.current_span++ 
                }
                else {
                    $.current_span = 0
                }
                if $.current_span > @spans.end {
                    $self.reset();
                    return;
                }
                my $span = @spans[$.current_span];
                $.current = $span.next( -Inf );
            }
            return $.current if $.current != Inf;
            undefine $.current;
        }
    }
    method previous ($self: ) {
        # TODO - simplify this
        my @spans = $.set.spans;
        loop {
            if defined $.current {
                my $span = @spans[$.current_span];
                $.current = $span.previous( $.current );                
            }
            else {
                if defined $.current_span {
                    $.current_span--
                }
                else {
                    $.current_span = @spans.end
                }
                if $.current_span < 0 {
                    $self.reset();
                    return;



( run in 0.453 second using v1.01-cache-2.11-cpan-e93a5daba3e )