package Data::Range::Compare::Stream; use strict; use warnings; use base qw(Data::Range::Compare::Stream::Result::Base); use Data::Range::Compare::Stream::Constants qw(RANGE_START RANGE_END RANGE_DATA); use constant NEW_FROM_CLASS=>'Data::Range::Compare::Stream'; our $VERSION='3.022'; sub to_string { my $notation=join ' - ',$_[0]->range_start_to_string,$_[0]->range_end_to_string; $notation; } sub range_start () { $_[0]->[RANGE_START] } sub range_end () { $_[0]->[RANGE_END] } sub range_start_to_string () { $_[0]->range_start } sub range_end_to_string () { $_[0]->range_end } sub on_create_range { } sub add_one ($) { my ($self,$value)=@_; $value + 1; } sub sub_one ($) { my ($self,$value)=@_; $value - 1; } sub cmp_values ($$) { my ($self,$value_a,$value_b)=@_; $value_a <=> $value_b } sub next_range_start () { $_[0]->add_one($_[0]->range_end) } sub previous_range_end () { $_[0]->sub_one($_[0]->range_start) } sub data { my ($self,$data)=@_; return $self->[RANGE_DATA] unless defined($data); $self->[$self->RANGE_DATA]=$data; } sub get_common_range ($) { my ($class,$ranges)=@_; my ($range_start,$range_end)=@{$ranges}[0,0]; for( my $x=1;$x<=$#$ranges;++$x) { $range_start=$ranges->[$x] if $class->cmp_values($range_start->range_start,$ranges->[$x]->range_start)==-1; $range_end=$ranges->[$x] if $class->cmp_values($range_end->range_end,$ranges->[$x]->range_end)==1; } my $new_range=$class->NEW_FROM_CLASS->new($range_start->range_start,$range_end->range_end); $new_range->on_create_range($range_start); $new_range; } sub find_smallest_outer_ranges { my ($self,$ref)=@_; my $start=$ref->[0]; my $end=$ref->[0]; foreach my $range (@$ref) { { my $cmp=$start->cmp_range_start($range); if($cmp==1) { $start=$range; } elsif($cmp==0 && $start->cmp_range_end($range)==1) { $start=$range; } } { my $cmp=$end->cmp_range_end($range); if($cmp==-1) { $end=$range; } elsif($cmp==0 && $end->cmp_range_start($range)==-1) { $end=$range; } } } return ($start,$end); } sub get_overlapping_range ($) { my ($class,$ranges)=@_; my ($range_start,$range_end)=@{$ranges}[0,0]; for( my $x=1;$x<=$#$ranges;++$x) { $range_start=$ranges->[$x] if $class->cmp_values($range_start->range_start,$ranges->[$x]->range_start)==1; $range_end=$ranges->[$x] if $class->cmp_values($range_end->range_end,$ranges->[$x]->range_end)==-1; } my $new_range=$class->NEW_FROM_CLASS->new($range_start->range_start,$range_end->range_end); $new_range->on_create_range($range_start); $new_range; } sub cmp_range_start($) { my ($self,$cmp)=@_; $self->cmp_values($self->range_start,$cmp->range_start) } sub cmp_range_end($) { my ($self,$cmp)=@_; $self->cmp_values($self->range_end,$cmp->range_end) } sub cmp_range_start_to_range_end ($) { my ($self,$cmp)=@_; $self->cmp_values($self->range_start,$cmp->range_end) } sub contains_value ($) { my ($self,$cmp)=@_; return 0 if $self->cmp_values($self->range_start,$cmp)==1; return 0 if $self->cmp_values($cmp,$self->range_end)==1; 1 } sub contiguous_check ($) { my ($cmp_a,$cmp_b)=@_; $cmp_a->cmp_values( $cmp_a->next_range_start ,$cmp_b->range_start )==0 } sub cmp_ranges ($) { my ($range_a,$range_b)=@_; my $cmp=$range_a->cmp_range_start($range_b); if($cmp==0) { return $range_a->cmp_range_end($range_b); } return $cmp; } sub overlap ($) { my ($range_a,$range_b)=@_; return 1 if $range_a->contains_value($range_b->range_start); return 1 if $range_a->contains_value($range_b->range_end); return 1 if $range_b->contains_value($range_a->range_start); return 1 if $range_b->contains_value($range_a->range_end); return 0 } 1;