diff options
Diffstat (limited to 'Data-TagsAndRanges/lib/Data/TagsAndRanges/RangeContainer.pm')
-rw-r--r-- | Data-TagsAndRanges/lib/Data/TagsAndRanges/RangeContainer.pm | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/Data-TagsAndRanges/lib/Data/TagsAndRanges/RangeContainer.pm b/Data-TagsAndRanges/lib/Data/TagsAndRanges/RangeContainer.pm new file mode 100644 index 0000000..5f3653a --- /dev/null +++ b/Data-TagsAndRanges/lib/Data/TagsAndRanges/RangeContainer.pm @@ -0,0 +1,91 @@ +package Data::TagsAndRanges::RangeContainer; +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::Types::Moose qw(Num Str Any Undef ArrayRef); +use MooseX::Types::Structured qw(Dict); +use Data::TagsAndRanges::Exceptions; + +has _storage => ( + is => 'rw', + isa => ArrayRef[ + Dict[ + from => Num|Undef, + to => Num|Undef, + value => Any, + ], + ], + init_arg => undef, + default => sub { [ ] }, +); + +sub get { + my ($self,$args) = @_; + + my $at = $args->{at}; + + my ($range) = $self->_get_slot_at($at); + + if (!$range) { + Data::TagsAndRanges::Exceptions::RangeNotFound->throw({ + value => $at, + }); + } + + return $range; +} + +sub _cmp_less { + return if !defined $_[0]; + return 1 if !defined $_[1]; + return $_[0] <= $_[1]; +} +sub _cmp_more { + return if !defined $_[0]; + return 1 if !defined $_[1]; + return $_[0] > $_[1]; +} +sub _cmp_eq { + return 1 if !defined($_[0]) && !defined($_[1]); + return if defined($_[0]) xor defined($_[1]); + return $_[0] == $_[1]; +} + +sub _get_slot_at { + my ($self,$at) = @_; + + for my $slot (@{$self->_storage}) { + next if _cmp_less($slot->{to},$at); + last if _cmp_more($slot->{from},$at); + return $slot; + } + return; +} + +sub set_or_create { + my ($self,$args) = @_; + + my $from = $args->{from}; + my $to = $args->{to}; + + my ($range) = $self->_get_slot_at($from); + + if ($range && _cmp_eq($range->{from},$from) && _cmp_eq($range->{to},$to)) { + return $range; + } + + $range = $self->_create_slot($from,$to); + return $range; +} + +sub _create_slot { + my ($self,$from,$to) = @_; + + push @{$self->_storage},{ + from => $from, + to => $to, + value => undef, + }; + return $self->_storage->[-1]; +} + +1; |