Perl6-Pugs

 view release on metacpan or  search on metacpan

ext/Span/lib/Span.pm  view on Meta::CPAN

}

method intersection ($self: $span is copy) returns List of Span {
    # return $self.clone if $self.is_empty;
    my ($span0, $span1) = _normalize_parameter( $self, $span );
    return $self.new( span => $span1 ) if $span1.is_empty;
    return $self.new( span => $span0 ) if $span0.is_empty;
    my @span = $span0.intersection( $span1 );
    return @span.map:{ $self.new( span => $_ ) };
}

method complement ($self: ) returns List of Span {
    my $span0 = $self.span;
    my @span0 = $span0.complement;
    return @span0.map:{ $self.new( span => $_ ) };
}

method difference ($self: $span is copy) returns List of Span {
    return $self.clone if $self.is_empty;

    my ($span0, $span1) = _normalize_parameter( $self, $span );

    # XXX - why this doesn't work?
    # say 'diff ' , $span0.stringify, ' to ', $span1.stringify;
    # my @span0 = $span0.difference( $span1.span );
    # return @span0.map:{ $self.new( span => $_ ) };

    my @span1 = $span1.complement;
    # say $_.stringify for @span1;
    @span1 = @span1.map:{ $self.intersection( $_ ) };
    return @span1;
}

method next ( $x ) { 
    return $.span.next( $x );
}

method previous ( $x ) { 
    return $.span.previous( $x );
}

method current ( $x ) {
    return $.span.next( $.span.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 Span::Iterator {
    if ( ! defined( $.span.density ) &&
         ! $.span.isa( 'Span::Code' ) )
    {
        warn "creating an iterator for a continuous Span";
    }
    return ::Span::Iterator.new( span => $.span );
}

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

} # class Span

class Span::Iterator
{
    has $.current;
    has $.span;
    submethod BUILD ( $.span ) {}
    method next () {
        if defined $.current {
            $.current = $.span.next( $.current )
        }
        else {
            $.current = $.span.next( -Inf )
        }
        undefine $.current if $.current == Inf;
        return $.current;
    }
    method previous () {
        if defined $.current {
            $.current = $.span.previous( $.current )
        }
        else {
            $.current = $.span.previous( Inf )
        }
        undefine $.current if $.current == -Inf;
        return $.current;
    }
    method reset () {
        undefine $.current;
    }
}

=kwid

= NAME

Span - An object representing a single span

= SYNOPSIS

    use Span;

    $int_span = Span.new( :int, start => 0, end => 10 );
    #  [10,20]   11 things
    
    $one_day = Date::Duration.new( days => 1 );
    $date_span = Span.new( :density($one_day), start => $dstart, end => $dend );
    # [2005-07-15,2005-07-20]    6 days

    $num_span = Span.new( start => -1.0, end => 2.5 );
    #  [-1.0,2.5]   
    



( run in 4.198 seconds using v1.01-cache-2.11-cpan-56fb94df46f )