File Coverage

blib/lib/Set/IntRange.pm
Criterion Covered Total %
statement 445 470 94.6
branch 221 250 88.4
condition 178 242 73.5
subroutine 63 65 96.9
pod 0 38 0.0
total 907 1065 85.1


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             ## ##
4             ## Copyright (c) 1995 - 2009 by Steffen Beyer. ##
5             ## All rights reserved. ##
6             ## ##
7             ## This package is free software; you can redistribute it ##
8             ## and/or modify it under the same terms as Perl itself. ##
9             ## ##
10             ###############################################################################
11              
12             package Set::IntRange;
13              
14 8     8   8457 use strict;
  8         14  
  8         282  
15 8     8   40 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
  8         13  
  8         1034  
16              
17             require Exporter;
18              
19             @ISA = qw(Exporter);
20              
21             @EXPORT = qw();
22              
23             @EXPORT_OK = qw();
24              
25             $VERSION = '5.2';
26              
27 8     8   44 use Carp;
  8         23  
  8         781  
28              
29 8     8   6347 use Bit::Vector 7.1;
  8         9515  
  8         973  
30              
31             use overload
32 8         73 '""' => '_string',
33             'neg' => '_complement',
34             '~' => '_complement',
35             'bool' => '_boolean',
36             '!' => '_not_boolean',
37             'abs' => '_norm',
38             '+' => '_union',
39             '|' => '_union', # alternative for '+'
40             '-' => '_difference',
41             '*' => '_intersection',
42             '&' => '_intersection', # alternative for '*'
43             '^' => '_exclusive_or',
44             '+=' => '_assign_union',
45             '|=' => '_assign_union', # alternative for '+='
46             '-=' => '_assign_difference',
47             '*=' => '_assign_intersection',
48             '&=' => '_assign_intersection', # alternative for '*='
49             '^=' => '_assign_exclusive_or',
50             '==' => '_equal',
51             '!=' => '_not_equal',
52             '<' => '_true_sub_set',
53             '<=' => '_sub_set',
54             '>' => '_true_super_set',
55             '>=' => '_super_set',
56             'cmp' => '_compare', # also enables lt, le, gt, ge, eq, ne
57             '=' => '_clone',
58 8     8   14903 'fallback' => undef;
  8         9286  
59              
60             sub new
61             {
62 191 100   191 0 5659 croak "Usage: \$set = Set::IntRange->new(\$lower,\$upper);"
63             if (@_ != 3);
64              
65 185         343 my $proto = shift;
66 185   100     765 my $class = ref($proto) || $proto || 'Set::IntRange';
67 185         250 my $lower = shift;
68 185         243 my $upper = shift;
69 185         196 my $object;
70             my $set;
71              
72 185 100       507 if ($lower <= $upper)
73             {
74 183         1173 $set = Bit::Vector->new($upper-$lower+1);
75 183 50 33     950 if ((defined $set) && ref($set) && (${$set} != 0))
  183   33     652  
76             {
77 183         447 $object = [ $set, $lower, $upper ];
78 183         355 bless($object, $class);
79 183         381 return($object);
80             }
81             else
82             {
83 0         0 croak
84             "Set::IntRange::new(): unable to create new 'Set::IntRange' object";
85             }
86             }
87             else
88             {
89 2         468 croak
90             "Set::IntRange::new(): lower > upper boundary";
91             }
92             }
93              
94             sub Resize
95             {
96 81 50   81 0 641 croak "Usage: \$set->Resize(\$lower,\$upper);"
97             if (@_ != 3);
98              
99 81         165 my($object,$new_lower,$new_upper) = @_;
100 81         160 my($old_lower,$old_upper) = ($object->[1],$object->[2]);
101 81         121 my($diff);
102              
103 81 100       155 if ($new_lower <= $new_upper)
104             {
105 73         97 $diff = $new_lower - $old_lower;
106 73 100       237 if ($diff == 0)
107             {
108 9         47 $object->[0]->Resize($new_upper-$new_lower+1);
109             }
110             else
111             {
112 64 100       174 if ($diff > 0)
113             {
114 37         254 $object->[0]->Delete(0,$diff);
115 37         174 $object->[0]->Resize($new_upper-$new_lower+1);
116             }
117             else
118             {
119 27         141 $object->[0]->Resize($new_upper-$new_lower+1);
120 27         229 $object->[0]->Insert(0,-$diff);
121             }
122             }
123 73         287 ($object->[1],$object->[2]) = ($new_lower,$new_upper);
124             }
125             else
126             {
127 8         1788 croak "Set::IntRange::Resize(): lower > upper boundary";
128             }
129             }
130              
131             sub Size
132             {
133 18 100   18 0 567 croak "Usage: (\$lower,\$upper) = \$set->Size();"
134             if (@_ != 1);
135              
136 16         19 my($object) = @_;
137              
138 16         53 return( $object->[1], $object->[2] );
139             }
140              
141             sub Bit_Vector
142             {
143 3 100   3 0 433 croak "Usage: \$set2->Bit_Vector->Bit_Vector_method(\$set1->Bit_Vector);"
144             if (@_ != 1);
145              
146 1         2 my($object) = @_;
147              
148 1         47 return( $object->[0] );
149             }
150              
151             sub Empty
152             {
153 7 100   7 0 532 croak "Usage: \$set->Empty();"
154             if (@_ != 1);
155              
156 5         10 my($object) = @_;
157              
158 5         26 $object->[0]->Empty();
159             }
160              
161             sub Fill
162             {
163 21 100   21 0 664 croak "Usage: \$set->Fill();"
164             if (@_ != 1);
165              
166 19         25 my($object) = @_;
167              
168 19         300 $object->[0]->Fill();
169             }
170              
171             sub Flip
172             {
173 4 100   4 0 543 croak "Usage: \$set->Flip();"
174             if (@_ != 1);
175              
176 2         4 my($object) = @_;
177              
178 2         20 $object->[0]->Flip();
179             }
180              
181             sub Interval_Empty
182             {
183 120 100   120 0 6660 croak "Usage: \$set->Interval_Empty(\$min,\$max);"
184             if (@_ != 3);
185              
186 116         173 my($object,$min,$max) = @_;
187 116         161 my($lower,$upper) = ($object->[1],$object->[2]);
188              
189 116 100 100     3031 croak "Set::IntRange::Interval_Empty(): minimum index out of range"
190             if (($min < $lower) || ($min > $upper));
191              
192 94 100 66     426 croak "Set::IntRange::Interval_Empty(): maximum index out of range"
193             if (($max < $lower) || ($max > $upper));
194              
195 93 100       244 croak "Set::IntRange::Interval_Empty(): minimum > maximum index"
196             if ($min > $max);
197              
198 92         607 $object->[0]->Interval_Empty($min-$lower,$max-$lower);
199             }
200              
201             sub Interval_Fill
202             {
203 121 100   121 0 6088 croak "Usage: \$set->Interval_Fill(\$min,\$max);"
204             if (@_ != 3);
205              
206 117         178 my($object,$min,$max) = @_;
207 117         288 my($lower,$upper) = ($object->[1],$object->[2]);
208              
209 117 100 100     3289 croak "Set::IntRange::Interval_Fill(): minimum index out of range"
210             if (($min < $lower) || ($min > $upper));
211              
212 95 100 66     444 croak "Set::IntRange::Interval_Fill(): maximum index out of range"
213             if (($max < $lower) || ($max > $upper));
214              
215 94 100       296 croak "Set::IntRange::Interval_Fill(): minimum > maximum index"
216             if ($min > $max);
217              
218 93         653 $object->[0]->Interval_Fill($min-$lower,$max-$lower);
219             }
220              
221             sub Interval_Flip
222             {
223 156 100   156 0 6432 croak "Usage: \$set->Interval_Flip(\$min,\$max);"
224             if (@_ != 3);
225              
226 152         196 my($object,$min,$max) = @_;
227 152         252 my($lower,$upper) = ($object->[1],$object->[2]);
228              
229 152 100 100     2957 croak "Set::IntRange::Interval_Flip(): minimum index out of range"
230             if (($min < $lower) || ($min > $upper));
231              
232 130 100 66     599 croak "Set::IntRange::Interval_Flip(): maximum index out of range"
233             if (($max < $lower) || ($max > $upper));
234              
235 129 100       313 croak "Set::IntRange::Interval_Flip(): minimum > maximum index"
236             if ($min > $max);
237              
238 128         707 $object->[0]->Interval_Flip($min-$lower,$max-$lower);
239             }
240              
241             sub Interval_Scan_inc
242             {
243 118 100   118 0 5826 croak "Usage: (\$min,\$max) = \$set->Interval_Scan_inc(\$start);"
244             if (@_ != 2);
245              
246 115         139 my($object,$start) = @_;
247 115         182 my($lower,$upper) = ($object->[1],$object->[2]);
248 115         113 my($min,$max);
249              
250 115 100 100     2964 croak "Set::IntRange::Interval_Scan_inc(): start index out of range"
251             if (($start < $lower) || ($start > $upper));
252              
253 92 50       475 if (($min,$max) = $object->[0]->Interval_Scan_inc($start-$lower))
254             {
255 92         107 $min += $lower;
256 92         88 $max += $lower;
257 92         502 return($min,$max);
258             }
259             else
260             {
261 0         0 return();
262             }
263             }
264              
265             sub Interval_Scan_dec
266             {
267 118 100   118 0 5300 croak "Usage: (\$min,\$max) = \$set->Interval_Scan_dec(\$start);"
268             if (@_ != 2);
269              
270 115         143 my($object,$start) = @_;
271 115         178 my($lower,$upper) = ($object->[1],$object->[2]);
272 115         113 my($min,$max);
273              
274 115 100 100     2900 croak "Set::IntRange::Interval_Scan_dec(): start index out of range"
275             if (($start < $lower) || ($start > $upper));
276              
277 92 100       465 if (($min,$max) = $object->[0]->Interval_Scan_dec($start-$lower))
278             {
279 70         83 $min += $lower;
280 70         65 $max += $lower;
281 70         302 return($min,$max);
282             }
283             else
284             {
285 22         125 return();
286             }
287             }
288              
289             sub Bit_Off
290             {
291 3422 100   3422 0 15775 croak "Usage: \$set->Bit_Off(\$index);"
292             if (@_ != 2);
293              
294 3419         3997 my($object,$index) = @_;
295 3419         5312 my($lower,$upper) = ($object->[1],$object->[2]);
296              
297 3419 100 100     17639 if (($index >= $lower) && ($index <= $upper))
298             {
299 3398         13923 $object->[0]->Bit_Off($index-$lower);
300             }
301             else
302             {
303 21         2397 croak "Set::IntRange::Bit_Off(): index out of range";
304             }
305             }
306              
307             sub Bit_On
308             {
309 1139 100   1139 0 7623 croak "Usage: \$set->Bit_On(\$index);"
310             if (@_ != 2);
311              
312 1136         1224 my($object,$index) = @_;
313 1136         1533 my($lower,$upper) = ($object->[1],$object->[2]);
314              
315 1136 100 100     3865 if (($index >= $lower) && ($index <= $upper))
316             {
317 1115         3580 $object->[0]->Bit_On($index-$lower);
318             }
319             else
320             {
321 21         2354 croak "Set::IntRange::Bit_On(): index out of range";
322             }
323             }
324              
325             sub bit_flip
326             {
327 122 100   122 0 6058 croak "Usage: if (\$set->bit_flip(\$index))"
328             if (@_ != 2);
329              
330 119         151 my($object,$index) = @_;
331 119         189 my($lower,$upper) = ($object->[1],$object->[2]);
332              
333 119 100 100     437 if (($index >= $lower) && ($index <= $upper))
334             {
335 98         637 return( $object->[0]->bit_flip($index-$lower) );
336             }
337             else
338             {
339 21         2561 croak "Set::IntRange::bit_flip(): index out of range";
340             }
341             }
342              
343             sub bit_test
344             {
345 103596 100   103596 0 480321 croak "Usage: if (\$set->bit_test(\$index))"
346             if (@_ != 2);
347              
348 103590         124276 my($object,$index) = @_;
349 103590         148261 my($lower,$upper) = ($object->[1],$object->[2]);
350              
351 103590 100 100     352441 if (($index >= $lower) && ($index <= $upper))
352             {
353 103548         452377 return( $object->[0]->bit_test($index-$lower) );
354             }
355             else
356             {
357 42         5148 croak "Set::IntRange::bit_test(): index out of range";
358             }
359             }
360              
361             sub contains
362             {
363 101     101 0 5304 return( bit_test(@_) );
364             }
365              
366             sub Norm
367             {
368 208 100   208 0 1203 croak "Usage: \$norm = \$set->Norm();"
369             if (@_ != 1);
370              
371 206         226 my($object) = @_;
372              
373 206         1385 return( $object->[0]->Norm() );
374             }
375              
376             sub Min
377             {
378 188 100   188 0 1901 croak "Usage: \$min = \$set->Min();"
379             if (@_ != 1);
380              
381 186         277 my($object) = @_;
382 186         355 my($lower,$upper) = ($object->[1],$object->[2]);
383 186         197 my($result);
384              
385 186         727 $result = $object->[0]->Min();
386 186 100 66     997 return( (($result >= 0) && ($result <= ($upper-$lower))) ?
387             ($result+$lower) : $result );
388             }
389              
390             sub Max
391             {
392 188 100   188 0 1576 croak "Usage: \$max = \$set->Max();"
393             if (@_ != 1);
394              
395 186         252 my($object) = @_;
396 186         278 my($lower,$upper) = ($object->[1],$object->[2]);
397 186         245 my($result);
398              
399 186         675 $result = $object->[0]->Max();
400 186 100 66     825 return( (($result >= 0) && ($result <= ($upper-$lower))) ?
401             ($result+$lower) : $result );
402             }
403              
404             sub Union
405             {
406 21 100   21 0 1425 croak "Usage: \$set1->Union(\$set2,\$set3);"
407             if (@_ != 3);
408              
409 17         27 my($set1,$set2,$set3) = @_;
410 17         30 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
411 17         23 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
412 17         26 my($lower3,$upper3) = ($set3->[1],$set3->[2]);
413              
414 17 100 100     119 if (($lower1 == $lower2) && ($lower1 == $lower3) &&
      66        
      66        
415             ($upper1 == $upper2) && ($upper1 == $upper3))
416             {
417 13         63 $set1->[0]->Union($set2->[0],$set3->[0]);
418             }
419             else
420             {
421 4         449 croak "Set::IntRange::Union(): set size mismatch";
422             }
423             }
424              
425             sub Intersection
426             {
427 21 100   21 0 1483 croak "Usage: \$set1->Intersection(\$set2,\$set3);"
428             if (@_ != 3);
429              
430 17         26 my($set1,$set2,$set3) = @_;
431 17         27 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
432 17         25 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
433 17         23 my($lower3,$upper3) = ($set3->[1],$set3->[2]);
434              
435 17 100 100     127 if (($lower1 == $lower2) && ($lower1 == $lower3) &&
      66        
      66        
436             ($upper1 == $upper2) && ($upper1 == $upper3))
437             {
438 13         72 $set1->[0]->Intersection($set2->[0],$set3->[0]);
439             }
440             else
441             {
442 4         467 croak "Set::IntRange::Intersection(): set size mismatch";
443             }
444             }
445              
446             sub Difference
447             {
448 16 100   16 0 1350 croak "Usage: \$set1->Difference(\$set2,\$set3);"
449             if (@_ != 3);
450              
451 12         18 my($set1,$set2,$set3) = @_;
452 12         21 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
453 12         18 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
454 12         18 my($lower3,$upper3) = ($set3->[1],$set3->[2]);
455              
456 12 100 100     86 if (($lower1 == $lower2) && ($lower1 == $lower3) &&
      66        
      66        
457             ($upper1 == $upper2) && ($upper1 == $upper3))
458             {
459 8         92 $set1->[0]->Difference($set2->[0],$set3->[0]);
460             }
461             else
462             {
463 4         450 croak "Set::IntRange::Difference(): set size mismatch";
464             }
465             }
466              
467             sub ExclusiveOr
468             {
469 13 100   13 0 1454 croak "Usage: \$set1->ExclusiveOr(\$set2,\$set3);"
470             if (@_ != 3);
471              
472 9         13 my($set1,$set2,$set3) = @_;
473 9         18 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
474 9         14 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
475 9         15 my($lower3,$upper3) = ($set3->[1],$set3->[2]);
476              
477 9 100 100     65 if (($lower1 == $lower2) && ($lower1 == $lower3) &&
      66        
      66        
478             ($upper1 == $upper2) && ($upper1 == $upper3))
479             {
480 5         41 $set1->[0]->ExclusiveOr($set2->[0],$set3->[0]);
481             }
482             else
483             {
484 4         471 croak "Set::IntRange::ExclusiveOr(): set size mismatch";
485             }
486             }
487              
488             sub Complement
489             {
490 14 100   14 0 867 croak "Usage: \$set1->Complement(\$set2);"
491             if (@_ != 2);
492              
493 11         14 my($set1,$set2) = @_;
494 11         33 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
495 11         41 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
496              
497 11 100 66     59 if (($lower1 == $lower2) && ($upper1 == $upper2))
498             {
499 10         65 $set1->[0]->Complement($set2->[0]);
500             }
501             else
502             {
503 1         122 croak "Set::IntRange::Complement(): set size mismatch";
504             }
505             }
506              
507             sub is_empty
508             {
509 51 100   51 0 650 croak "Usage: if (\$set->is_empty())"
510             if (@_ != 1);
511              
512 49         56 my($object) = @_;
513              
514 49         281 return( $object->[0]->is_empty() );
515             }
516              
517             sub is_full
518             {
519 35 100   35 0 617 croak "Usage: if (\$set->is_full())"
520             if (@_ != 1);
521              
522 33         36 my($object) = @_;
523              
524 33         116 return( $object->[0]->is_full() );
525             }
526              
527             sub equal
528             {
529 148 100   148 0 1942 croak "Usage: if (\$set1->equal(\$set2))"
530             if (@_ != 2);
531              
532 145         199 my($set1,$set2) = @_;
533 145         238 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
534 145         258 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
535              
536 145 100 66     544 if (($lower1 == $lower2) && ($upper1 == $upper2))
537             {
538 144         842 return( $set1->[0]->equal($set2->[0]) );
539             }
540             else
541             {
542 1         109 croak "Set::IntRange::equal(): set size mismatch";
543             }
544             }
545              
546             sub subset
547             {
548 29 100   29 0 800 croak "Usage: if (\$set1->subset(\$set2))"
549             if (@_ != 2);
550              
551 26         33 my($set1,$set2) = @_;
552 26         37 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
553 26         32 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
554              
555 26 100 66     89 if (($lower1 == $lower2) && ($upper1 == $upper2))
556             {
557 25         164 return( $set1->[0]->subset($set2->[0]) );
558             }
559             else
560             {
561 1         108 croak "Set::IntRange::subset(): set size mismatch";
562             }
563             }
564              
565             sub Lexicompare
566             {
567 5 100   5 0 727 croak "Usage: \$cmp = \$set1->Lexicompare(\$set2);"
568             if (@_ != 2);
569              
570 2         3 my($set1,$set2) = @_;
571 2         5 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
572 2         3 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
573              
574 2 100 66     12 if (($lower1 == $lower2) && ($upper1 == $upper2))
575             {
576 1         11 return( $set1->[0]->Lexicompare($set2->[0]) );
577             }
578             else
579             {
580 1         106 croak "Set::IntRange::Lexicompare(): set size mismatch";
581             }
582             }
583              
584             sub Compare
585             {
586 26 100   26 0 917 croak "Usage: \$cmp = \$set1->Compare(\$set2);"
587             if (@_ != 2);
588              
589 23         26 my($set1,$set2) = @_;
590 23         34 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
591 23         31 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
592              
593 23 100 66     79 if (($lower1 == $lower2) && ($upper1 == $upper2))
594             {
595 22         114 return( $set1->[0]->Compare($set2->[0]) );
596             }
597             else
598             {
599 1         135 croak "Set::IntRange::Compare(): set size mismatch";
600             }
601             }
602              
603             sub Copy
604             {
605 108 100   108 0 1082 croak "Usage: \$set1->Copy(\$set2);"
606             if (@_ != 2);
607              
608 105         145 my($set1,$set2) = @_;
609 105         240 my($lower1,$upper1) = ($set1->[1],$set1->[2]);
610 105         184 my($lower2,$upper2) = ($set2->[1],$set2->[2]);
611              
612 105 100 66     447 if (($lower1 == $lower2) && ($upper1 == $upper2))
613             {
614 104         558 $set1->[0]->Copy($set2->[0]);
615             }
616             else
617             {
618 1         177 croak "Set::IntRange::Copy(): set size mismatch";
619             }
620             }
621              
622             sub Shadow
623             {
624 1 50   1 0 31 croak "Usage: \$other_set = \$some_set->Shadow();"
625             if (@_ != 1);
626              
627 1         3 my($object) = @_;
628 1         1 my($result);
629              
630 1         3 $result = $object->new($object->[1],$object->[2]);
631 1         3 return($result);
632             }
633              
634             sub Clone
635             {
636 81 50   81 0 2621 croak "Usage: \$twin_set = \$some_set->Clone();"
637             if (@_ != 1);
638              
639 81         158 my($object) = @_;
640 81         120 my($result);
641              
642 81         340 $result = $object->new($object->[1],$object->[2]);
643 81         326 $result->Copy($object);
644 81         266 return($result);
645             }
646              
647             sub to_Enum
648             {
649 1 50   1 0 9 croak "Usage: \$string = \$set->to_Enum();"
650             if (@_ != 1);
651              
652 1         2 my($object) = @_;
653 1         2 my($lower) = $object->[1];
654 1         2 my($start,$string);
655 0         0 my($min,$max);
656              
657 1         1 $start = 0;
658 1         2 $string = '';
659 1   66     16 while (($start < $object->[0]->Size()) &&
660             (($min,$max) = $object->[0]->Interval_Scan_inc($start)))
661             {
662 38         37 $start = $max + 2;
663 38         30 $min += $lower;
664 38         36 $max += $lower;
665 38 100       69 if ($min == $max) { $string .= "${min},"; }
  33 100       204  
666 1         10 elsif ($min == $max-1) { $string .= "${min},${max},"; }
667 4         28 else { $string .= "${min}..${max},"; }
668             }
669 1         7 $string =~ s/,$//;
670 1         3 return($string);
671             }
672              
673             sub from_Enum
674             {
675 7 50   7 0 135 croak "Usage: \$set->from_Enum(\$string);"
676             if (@_ != 2);
677              
678 7         13 my($object,$string) = @_;
679 7         9 my($lower,$upper) = ($object->[1],$object->[2]);
680 7         5 my(@intervals,$interval);
681 0         0 my($min,$max);
682              
683 7 50       120 croak "Set::IntRange::from_Enum(): syntax error in input string"
684             unless ($string =~ /^ (?: [+-]? \d+ (?: \.\. [+-]? \d+ )? )
685             (?: , (?: [+-]? \d+ (?: \.\. [+-]? \d+ )? ) )* $/x);
686              
687 7         18 $object->[0]->Empty();
688              
689 7         34 @intervals = split(/,/, $string);
690              
691 7         11 foreach $interval (@intervals)
692             {
693 83 100       129 if ($interval =~ /\.\./)
694             {
695 13         25 ($min,$max) = split(/\.\./, $interval);
696              
697 13 100 66     236 croak "Set::IntRange::from_Enum(): minimum index out of range"
698             if (($min < $lower) || ($min > $upper));
699              
700 12 100 66     126 croak "Set::IntRange::from_Enum(): maximum index out of range"
701             if (($max < $lower) || ($max > $upper));
702              
703 11 100       97 croak "Set::IntRange::from_Enum(): minimum > maximum index"
704             if ($min > $max);
705              
706 10         8 $min -= $lower;
707 10         9 $max -= $lower;
708              
709 10         29 $object->[0]->Interval_Fill($min,$max);
710             }
711             else
712             {
713 70 50 33     228 croak "Set::IntRange::from_Enum(): index out of range"
714             if (($interval < $lower) || ($interval > $upper));
715              
716 70         58 $interval -= $lower;
717              
718 70         149 $object->[0]->Bit_On($interval);
719             }
720             }
721             }
722              
723             sub to_Hex
724             {
725 1 50   1 0 11 croak "Usage: \$string = \$set->to_Hex();"
726             if (@_ != 1);
727              
728 1         2 my($object) = @_;
729              
730 1         7 return( $object->[0]->to_Hex() );
731             }
732              
733             sub from_Hex
734             {
735 1 50   1 0 7 croak "Usage: \$set->from_Hex(\$string);"
736             if (@_ != 2);
737              
738 1         1 my($object,$string) = @_;
739              
740 1         2 eval { $object->[0]->from_Hex($string); };
  1         71  
741 1 50       5 if ($@)
742             {
743 0         0 croak "Set::IntRange::from_Hex(): syntax error in input string";
744             }
745             }
746              
747             ########################################
748             # #
749             # define overloaded operators section: #
750             # #
751             ########################################
752              
753             sub _string
754             {
755 0     0   0 my($object,$argument,$flag) = @_;
756             # my($name) = '""'; #&_trace($name,$object,$argument,$flag);
757 0         0 my($vector) = $object->[0];
758              
759 0         0 return( "$vector" );
760             }
761              
762             sub _complement
763             {
764 6     6   7 my($object,$argument,$flag) = @_;
765             # my($name) = "'~'"; #&_trace($name,$object,$argument,$flag);
766 6         9 my($result);
767              
768 6         22 $result = $object->new($object->[1],$object->[2]);
769 6         15 $result->Complement($object);
770 6         17 return($result);
771             }
772              
773             sub _boolean
774             {
775 7     7   42 my($object,$argument,$flag) = @_;
776             # my($name) = "bool"; #&_trace($name,$object,$argument,$flag);
777              
778 7         12 return( ! $object->is_empty() );
779             }
780              
781             sub _not_boolean
782             {
783 9     9   47 my($object,$argument,$flag) = @_;
784             # my($name) = "'!'"; #&_trace($name,$object,$argument,$flag);
785              
786 9         19 return( $object->is_empty() );
787             }
788              
789             sub _norm
790             {
791 35     35   215 my($object,$argument,$flag) = @_;
792             # my($name) = "abs"; #&_trace($name,$object,$argument,$flag);
793              
794 35         63 return( $object->Norm() );
795             }
796              
797             sub _union
798             {
799 1041     1041   4551 my($object,$argument,$flag) = @_;
800 1041         1040 my($name) = "'+'"; #&_trace($name,$object,$argument,$flag);
801 1041         868 my($result);
802              
803 1041 100 66     6472 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
804             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
805             {
806 12 100       23 if (defined $flag)
807             {
808 10         24 $result = $object->new($object->[1],$object->[2]);
809 10         23 $result->Union($object,$argument);
810 10         29 return($result);
811             }
812             else
813             {
814 2         5 $object->Union($object,$argument);
815 2         6 return($object);
816             }
817             }
818             elsif ((defined $argument) && !(ref($argument)))
819             {
820 1009 100       1454 if (defined $flag)
821             {
822 5         14 $result = $object->new($object->[1],$object->[2]);
823 5         13 $result->Copy($object);
824 5         9 $result->Bit_On($argument);
825 5         18 return($result);
826             }
827             else
828             {
829 1004         1486 $object->Bit_On($argument);
830 1004         2591 return($object);
831             }
832             }
833             else
834             {
835 20         3576 croak "Set::IntRange $name: wrong argument type";
836             }
837             }
838              
839             sub _difference
840             {
841 1645     1645   5847 my($object,$argument,$flag) = @_;
842 1645         1653 my($name) = "'-'"; #&_trace($name,$object,$argument,$flag);
843 1645         1408 my($result);
844              
845 1645 100 66     10276 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
846             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
847             {
848 7 100       16 if (defined $flag)
849             {
850 6         18 $result = $object->new($object->[1],$object->[2]);
851 6 50       13 if ($flag) { $result->Difference($argument,$object); }
  0         0  
852 6         28 else { $result->Difference($object,$argument); }
853 6         19 return($result);
854             }
855             else
856             {
857 1         3 $object->Difference($object,$argument);
858 1         4 return($object);
859             }
860             }
861             elsif ((defined $argument) && !(ref($argument)))
862             {
863 1628 100       2350 if (defined $flag)
864             {
865 3         9 $result = $object->new($object->[1],$object->[2]);
866 3 50       6 if ($flag)
867             {
868 0 0       0 unless ($object->bit_test($argument))
869 0         0 { $result->Bit_On($argument); }
870             }
871             else
872             {
873 3         6 $result->Copy($object);
874 3         9 $result->Bit_Off($argument);
875             }
876 3         9 return($result);
877             }
878             else
879             {
880 1625         2420 $object->Bit_Off($argument);
881 1625         4013 return($object);
882             }
883             }
884             else
885             {
886 10         1631 croak "Set::IntRange $name: wrong argument type";
887             }
888             }
889              
890             sub _intersection
891             {
892 36     36   2628 my($object,$argument,$flag) = @_;
893 36         46 my($name) = "'*'"; #&_trace($name,$object,$argument,$flag);
894 36         37 my($result);
895              
896 36 100 66     377 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
897             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
898             {
899 12 100       23 if (defined $flag)
900             {
901 10         25 $result = $object->new($object->[1],$object->[2]);
902 10         34 $result->Intersection($object,$argument);
903 10         29 return($result);
904             }
905             else
906             {
907 2         5 $object->Intersection($object,$argument);
908 2         5 return($object);
909             }
910             }
911             elsif ((defined $argument) && !(ref($argument)))
912             {
913 4 100       10 if (defined $flag)
914             {
915 2         6 $result = $object->new($object->[1],$object->[2]);
916 2 50       6 if ($object->bit_test($argument))
917 2         5 { $result->Bit_On($argument); }
918 2         5 return($result);
919             }
920             else
921             {
922 2         5 $flag = $object->bit_test($argument);
923 2         5 $object->Empty();
924 2 50       3 if ($flag) { $object->Bit_On($argument); }
  2         4  
925 2         6 return($object);
926             }
927             }
928             else
929             {
930 20         2261 croak "Set::IntRange $name: wrong argument type";
931             }
932             }
933              
934             sub _exclusive_or
935             {
936 19     19   1356 my($object,$argument,$flag) = @_;
937 19         34 my($name) = "'^'"; #&_trace($name,$object,$argument,$flag);
938 19         24 my($result);
939              
940 19 100 66     219 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
941             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
942             {
943 3 100       7 if (defined $flag)
944             {
945 2         6 $result = $object->new($object->[1],$object->[2]);
946 2         8 $result->ExclusiveOr($object,$argument);
947 2         6 return($result);
948             }
949             else
950             {
951 1         3 $object->ExclusiveOr($object,$argument);
952 1         3 return($object);
953             }
954             }
955             elsif ((defined $argument) && !(ref($argument)))
956             {
957 6 100       12 if (defined $flag)
958             {
959 1         3 $result = $object->new($object->[1],$object->[2]);
960 1         3 $result->Copy($object);
961 1         3 $result->bit_flip($argument);
962 1         4 return($result);
963             }
964             else
965             {
966 5         16 $object->bit_flip($argument);
967 5         16 return($object);
968             }
969             }
970             else
971             {
972 10         1206 croak "Set::IntRange $name: wrong argument type";
973             }
974             }
975              
976             sub _assign_union
977             {
978 1006     1006   3039 my($object,$argument,$flag) = @_;
979             # my($name) = "'+='"; #&_trace($name,$object,$argument,$flag);
980              
981 1006         1423 return( &_union($object,$argument,undef) );
982             }
983              
984             sub _assign_difference
985             {
986 1626     1626   4913 my($object,$argument,$flag) = @_;
987             # my($name) = "'-='"; #&_trace($name,$object,$argument,$flag);
988              
989 1626         2308 return( &_difference($object,$argument,undef) );
990             }
991              
992             sub _assign_intersection
993             {
994 4     4   18 my($object,$argument,$flag) = @_;
995             # my($name) = "'*='"; #&_trace($name,$object,$argument,$flag);
996              
997 4         9 return( &_intersection($object,$argument,undef) );
998             }
999              
1000             sub _assign_exclusive_or
1001             {
1002 6     6   42 my($object,$argument,$flag) = @_;
1003             # my($name) = "'^='"; #&_trace($name,$object,$argument,$flag);
1004              
1005 6         20 return( &_exclusive_or($object,$argument,undef) );
1006             }
1007              
1008             sub _equal
1009             {
1010 52     52   1354 my($object,$argument,$flag) = @_;
1011 52         63 my($name) = "'=='"; #&_trace($name,$object,$argument,$flag);
1012 52         48 my($result);
1013              
1014 52 100 66     502 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1015             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1016             {
1017 30         33 $result = $argument;
1018             }
1019             elsif ((defined $argument) && !(ref($argument)))
1020             {
1021 12         28 $result = $object->new($object->[1],$object->[2]);
1022 12         25 $result->Bit_On($argument);
1023             }
1024             else
1025             {
1026 10         1071 croak "Set::IntRange $name: wrong argument type";
1027             }
1028 42         78 return( $object->equal($result) );
1029             }
1030              
1031             sub _not_equal
1032             {
1033 13     13   1209 my($object,$argument,$flag) = @_;
1034 13         19 my($name) = "'!='"; #&_trace($name,$object,$argument,$flag);
1035 13         15 my($result);
1036              
1037 13 100 33     145 if ((defined $argument) && ref($argument) &&
    50 66        
      33        
1038             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1039             {
1040 3         3 $result = $argument;
1041             }
1042             elsif ((defined $argument) && !(ref($argument)))
1043             {
1044 0         0 $result = $object->new($object->[1],$object->[2]);
1045 0         0 $result->Bit_On($argument);
1046             }
1047             else
1048             {
1049 10         1070 croak "Set::IntRange $name: wrong argument type";
1050             }
1051 3         7 return( !($object->equal($result)) );
1052             }
1053              
1054             sub _true_sub_set
1055             {
1056 16     16   1264 my($object,$argument,$flag) = @_;
1057 16         23 my($name) = "'<'"; #&_trace($name,$object,$argument,$flag);
1058 16         17 my($result);
1059              
1060 16 100 66     226 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1061             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1062             {
1063 4         5 $result = $argument;
1064             }
1065             elsif ((defined $argument) && !(ref($argument)))
1066             {
1067 2         6 $result = $object->new($object->[1],$object->[2]);
1068 2         4 $result->Bit_On($argument);
1069             }
1070             else
1071             {
1072 10         1186 croak "Set::IntRange $name: wrong argument type";
1073             }
1074 6 100 66     22 if ((defined $flag) && $flag)
1075             {
1076 1   33     3 return( !($result->equal($object)) &&
1077             ($result->subset($object)) );
1078             }
1079             else
1080             {
1081 5   66     10 return( !($object->equal($result)) &&
1082             ($object->subset($result)) );
1083             }
1084             }
1085              
1086             sub _sub_set
1087             {
1088 16     16   1288 my($object,$argument,$flag) = @_;
1089 16         22 my($name) = "'<='"; #&_trace($name,$object,$argument,$flag);
1090 16         20 my($result);
1091              
1092 16 100 66     179 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1093             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1094             {
1095 4         5 $result = $argument;
1096             }
1097             elsif ((defined $argument) && !(ref($argument)))
1098             {
1099 2         5 $result = $object->new($object->[1],$object->[2]);
1100 2         3 $result->Bit_On($argument);
1101             }
1102             else
1103             {
1104 10         1150 croak "Set::IntRange $name: wrong argument type";
1105             }
1106 6 100 66     21 if ((defined $flag) && $flag)
1107             {
1108 1         3 return( $result->subset($object) );
1109             }
1110             else
1111             {
1112 5         16 return( $object->subset($result) );
1113             }
1114             }
1115              
1116             sub _true_super_set
1117             {
1118 16     16   1395 my($object,$argument,$flag) = @_;
1119 16         22 my($name) = "'>'"; #&_trace($name,$object,$argument,$flag);
1120 16         16 my($result);
1121              
1122 16 100 66     201 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1123             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1124             {
1125 4         5 $result = $argument;
1126             }
1127             elsif ((defined $argument) && !(ref($argument)))
1128             {
1129 2         5 $result = $object->new($object->[1],$object->[2]);
1130 2         5 $result->Bit_On($argument);
1131             }
1132             else
1133             {
1134 10         1187 croak "Set::IntRange $name: wrong argument type";
1135             }
1136 6 100 66     20 if ((defined $flag) && $flag)
1137             {
1138 1   33     3 return( !($object->equal($result)) &&
1139             ($object->subset($result)) );
1140             }
1141             else
1142             {
1143 5   66     11 return( !($result->equal($object)) &&
1144             ($result->subset($object)) );
1145             }
1146             }
1147              
1148             sub _super_set
1149             {
1150 16     16   1344 my($object,$argument,$flag) = @_;
1151 16         24 my($name) = "'>='"; #&_trace($name,$object,$argument,$flag);
1152 16         19 my($result);
1153              
1154 16 100 66     178 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1155             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1156             {
1157 4         6 $result = $argument;
1158             }
1159             elsif ((defined $argument) && !(ref($argument)))
1160             {
1161 2         6 $result = $object->new($object->[1],$object->[2]);
1162 2         5 $result->Bit_On($argument);
1163             }
1164             else
1165             {
1166 10         1182 croak "Set::IntRange $name: wrong argument type";
1167             }
1168 6 100 66     22 if ((defined $flag) && $flag)
1169             {
1170 1         2 return( $object->subset($result) );
1171             }
1172             else
1173             {
1174 5         15 return( $result->subset($object) );
1175             }
1176             }
1177              
1178             sub _compare
1179             {
1180 91     91   9225 my($object,$argument,$flag) = @_;
1181 91         126 my($name) = "cmp"; #&_trace($name,$object,$argument,$flag);
1182 91         97 my($result);
1183              
1184 91 100 66     1009 if ((defined $argument) && ref($argument) &&
    100 100        
      66        
1185             (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
1186             {
1187 19         22 $result = $argument;
1188             }
1189             elsif ((defined $argument) && !(ref($argument)))
1190             {
1191 2         5 $result = $object->new($object->[1],$object->[2]);
1192 2         6 $result->Bit_On($argument);
1193             }
1194             else
1195             {
1196 70         8447 croak "Set::IntRange $name: wrong argument type";
1197             }
1198 21 100 66     76 if ((defined $flag) && $flag)
1199             {
1200 1         3 return( $result->Compare($object) );
1201             }
1202             else
1203             {
1204 20         32 return( $object->Compare($result) );
1205             }
1206             }
1207              
1208             sub _clone
1209             {
1210 1     1   7 my($object,$argument,$flag) = @_;
1211             # my($name) = "'='"; #&_trace($name,$object,$argument,$flag);
1212 1         2 my($result);
1213              
1214 1         3 $result = $object->new($object->[1],$object->[2]);
1215 1         4 $result->Copy($object);
1216 1         9 return($result);
1217             }
1218              
1219             sub _trace
1220             {
1221 0     0     my($text,$object,$argument,$flag) = @_;
1222              
1223 0 0         unless (defined $object) { $object = 'undef'; };
  0            
1224 0 0         unless (defined $argument) { $argument = 'undef'; };
  0            
1225 0 0         unless (defined $flag) { $flag = 'undef'; };
  0            
1226 0 0         if (ref($object)) { $object = ref($object); }
  0            
1227 0 0         if (ref($argument)) { $argument = ref($argument); }
  0            
1228 0           print "$text: \$obj='$object' \$arg='$argument' \$flag='$flag'\n";
1229             }
1230              
1231             1;
1232              
1233             __END__