File Coverage

blib/lib/Bit/Vector/Overload.pm
Criterion Covered Total %
statement 300 596 50.3
branch 96 296 32.4
condition 34 177 19.2
subroutine 45 56 80.3
pod 0 1 0.0
total 475 1126 42.1


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             ## ##
4             ## Copyright (c) 2000 - 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 Bit::Vector::Overload;
13              
14 4     4   2182 use strict;
  4         6  
  4         122  
15 4     4   16 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
  4         5  
  4         260  
16              
17 4     4   1141 use Bit::Vector;
  4         8  
  4         343  
18              
19             require Exporter;
20              
21             @ISA = qw(Exporter Bit::Vector);
22              
23             @EXPORT = qw();
24              
25             @EXPORT_OK = qw();
26              
27             $VERSION = '7.2';
28              
29             package Bit::Vector;
30              
31 4     4   1994 use Carp::Clan '^Bit::Vector\b';
  4         12924  
  4         27  
32              
33             use overload
34 4         36 '""' => '_stringify',
35             'bool' => '_boolean',
36             '!' => '_not_boolean',
37             '~' => '_complement',
38             'neg' => '_negate',
39             'abs' => '_absolute',
40             '.' => '_concat',
41             'x' => '_xerox',
42             '<<' => '_shift_left',
43             '>>' => '_shift_right',
44             '|' => '_union',
45             '&' => '_intersection',
46             '^' => '_exclusive_or',
47             '+' => '_add',
48             '-' => '_sub',
49             '*' => '_mul',
50             '/' => '_div',
51             '%' => '_mod',
52             '**' => '_pow',
53             '.=' => '_assign_concat',
54             'x=' => '_assign_xerox',
55             '<<=' => '_assign_shift_left',
56             '>>=' => '_assign_shift_right',
57             '|=' => '_assign_union',
58             '&=' => '_assign_intersection',
59             '^=' => '_assign_exclusive_or',
60             '+=' => '_assign_add',
61             '-=' => '_assign_sub',
62             '*=' => '_assign_mul',
63             '/=' => '_assign_div',
64             '%=' => '_assign_mod',
65             '**=' => '_assign_pow',
66             '++' => '_increment',
67             '--' => '_decrement',
68             'cmp' => '_lexicompare', # also enables lt, le, gt, ge, eq, ne
69             '<=>' => '_compare',
70             '==' => '_equal',
71             '!=' => '_not_equal',
72             '<' => '_less_than',
73             '<=' => '_less_equal',
74             '>' => '_greater_than',
75             '>=' => '_greater_equal',
76             '=' => '_clone',
77 4     4   924 'fallback' => undef;
  4         34  
78              
79             $CONFIG[0] = 0;
80             $CONFIG[1] = 0;
81             $CONFIG[2] = 0;
82              
83             # Configuration:
84             #
85             # 0 = Scalar Input: 0 = Bit Index (default)
86             # 1 = from_Hex
87             # 2 = from_Bin
88             # 3 = from_Dec
89             # 4 = from_Enum
90             #
91             # 1 = Operator Semantics: 0 = Set Ops (default)
92             # 1 = Arithmetic Ops
93             #
94             # Affected Operators: "+" "-" "*"
95             # "<" "<=" ">" ">="
96             # "abs"
97             #
98             # 2 = String Output: 0 = to_Hex() (default)
99             # 1 = to_Bin()
100             # 2 = to_Dec()
101             # 3 = to_Enum()
102              
103             sub Configuration
104             {
105 0     0 0 0 my(@commands);
106             my($assignment);
107 0         0 my($which,$value);
108 0         0 my($m0,$m1,$m2,$m3,$m4);
109 0         0 my($result);
110 0         0 my($ok);
111              
112 0 0       0 if (@_ > 2)
113             {
114 0         0 croak('Usage: $oldconfig = Bit::Vector->Configuration( [ $newconfig ] );');
115             }
116 0         0 $result = "Scalar Input = ";
117 0 0       0 if ($CONFIG[0] == 4) { $result .= "Enumeration"; }
  0 0       0  
    0          
    0          
118 0         0 elsif ($CONFIG[0] == 3) { $result .= "Decimal"; }
119 0         0 elsif ($CONFIG[0] == 2) { $result .= "Binary"; }
120 0         0 elsif ($CONFIG[0] == 1) { $result .= "Hexadecimal"; }
121 0         0 else { $result .= "Bit Index"; }
122 0         0 $result .= "\nOperator Semantics = ";
123 0 0       0 if ($CONFIG[1] == 1) { $result .= "Arithmetic Operators"; }
  0         0  
124 0         0 else { $result .= "Set Operators"; }
125 0         0 $result .= "\nString Output = ";
126 0 0       0 if ($CONFIG[2] == 3) { $result .= "Enumeration"; }
  0 0       0  
    0          
127 0         0 elsif ($CONFIG[2] == 2) { $result .= "Decimal"; }
128 0         0 elsif ($CONFIG[2] == 1) { $result .= "Binary"; }
129 0         0 else { $result .= "Hexadecimal"; }
130 0 0       0 shift if (@_ > 0);
131 0 0       0 if (@_ > 0)
132             {
133 0         0 $ok = 1;
134 0         0 @commands = split(/[,;:|\/\n&+-]/, $_[0]);
135 0         0 foreach $assignment (@commands)
136             {
137 0 0       0 if ($assignment =~ /^\s*$/) { } # ignore empty lines
    0          
138             elsif ($assignment =~ /^([A-Za-z\s]+)=([A-Za-z\s]+)$/)
139             {
140 0         0 $which = $1;
141 0         0 $value = $2;
142 0         0 $m0 = 0;
143 0         0 $m1 = 0;
144 0         0 $m2 = 0;
145 0 0       0 if ($which =~ /\bscalar|\binput|\bin\b/i) { $m0 = 1; }
  0         0  
146 0 0       0 if ($which =~ /\boperator|\bsemantic|\bops\b/i) { $m1 = 1; }
  0         0  
147 0 0       0 if ($which =~ /\bstring|\boutput|\bout\b/i) { $m2 = 1; }
  0         0  
148 0 0 0     0 if ($m0 && !$m1 && !$m2)
    0 0        
    0 0        
      0        
      0        
      0        
149             {
150 0         0 $m0 = 0;
151 0         0 $m1 = 0;
152 0         0 $m2 = 0;
153 0         0 $m3 = 0;
154 0         0 $m4 = 0;
155 0 0       0 if ($value =~ /\bbit\b|\bindex|\bindice/i) { $m0 = 1; }
  0         0  
156 0 0       0 if ($value =~ /\bhex/i) { $m1 = 1; }
  0         0  
157 0 0       0 if ($value =~ /\bbin/i) { $m2 = 1; }
  0         0  
158 0 0       0 if ($value =~ /\bdec/i) { $m3 = 1; }
  0         0  
159 0 0       0 if ($value =~ /\benum/i) { $m4 = 1; }
  0         0  
160 0 0 0     0 if ($m0 && !$m1 && !$m2 && !$m3 && !$m4) { $CONFIG[0] = 0; }
  0 0 0     0  
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
161 0         0 elsif (!$m0 && $m1 && !$m2 && !$m3 && !$m4) { $CONFIG[0] = 1; }
162 0         0 elsif (!$m0 && !$m1 && $m2 && !$m3 && !$m4) { $CONFIG[0] = 2; }
163 0         0 elsif (!$m0 && !$m1 && !$m2 && $m3 && !$m4) { $CONFIG[0] = 3; }
164 0         0 elsif (!$m0 && !$m1 && !$m2 && !$m3 && $m4) { $CONFIG[0] = 4; }
165 0         0 else { $ok = 0; last; }
  0         0  
166             }
167             elsif (!$m0 && $m1 && !$m2)
168             {
169 0         0 $m0 = 0;
170 0         0 $m1 = 0;
171 0 0       0 if ($value =~ /\bset\b/i) { $m0 = 1; }
  0         0  
172 0 0       0 if ($value =~ /\barithmetic/i) { $m1 = 1; }
  0         0  
173 0 0 0     0 if ($m0 && !$m1) { $CONFIG[1] = 0; }
  0 0 0     0  
174 0         0 elsif (!$m0 && $m1) { $CONFIG[1] = 1; }
175 0         0 else { $ok = 0; last; }
  0         0  
176             }
177             elsif (!$m0 && !$m1 && $m2)
178             {
179 0         0 $m0 = 0;
180 0         0 $m1 = 0;
181 0         0 $m2 = 0;
182 0         0 $m3 = 0;
183 0 0       0 if ($value =~ /\bhex/i) { $m0 = 1; }
  0         0  
184 0 0       0 if ($value =~ /\bbin/i) { $m1 = 1; }
  0         0  
185 0 0       0 if ($value =~ /\bdec/i) { $m2 = 1; }
  0         0  
186 0 0       0 if ($value =~ /\benum/i) { $m3 = 1; }
  0         0  
187 0 0 0     0 if ($m0 && !$m1 && !$m2 && !$m3) { $CONFIG[2] = 0; }
  0 0 0     0  
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
188 0         0 elsif (!$m0 && $m1 && !$m2 && !$m3) { $CONFIG[2] = 1; }
189 0         0 elsif (!$m0 && !$m1 && $m2 && !$m3) { $CONFIG[2] = 2; }
190 0         0 elsif (!$m0 && !$m1 && !$m2 && $m3) { $CONFIG[2] = 3; }
191 0         0 else { $ok = 0; last; }
  0         0  
192             }
193 0         0 else { $ok = 0; last; }
  0         0  
194             }
195 0         0 else { $ok = 0; last; }
  0         0  
196             }
197 0 0       0 unless ($ok)
198             {
199 0         0 croak('configuration string syntax error');
200             }
201             }
202 0         0 return($result);
203             }
204              
205             sub _error
206             {
207 286     286   226 my($name,$code) = @_;
208 286         189 my($text);
209              
210 286 50       397 if ($code == 0)
    100          
    50          
211             {
212 0         0 $text = $@;
213 0         0 $text =~ s!\s+! !g;
214 0         0 $text =~ s!\s+at\s.*$!!;
215 0         0 $text =~ s!^(?:Bit::Vector::)?[a-zA-Z0-9_]+\(\):\s*!!i;
216 0         0 $text =~ s!\s+$!!;
217             }
218 280         233 elsif ($code == 1) { $text = 'illegal operand type'; }
219 6         8 elsif ($code == 2) { $text = 'illegal reversed operands'; }
220 0         0 else { croak('unexpected internal error - please contact author'); }
221 286         244 $text .= " in overloaded ";
222 286 50       301 if (length($name) > 5) { $text .= "$name operation"; }
  0         0  
223 286         251 else { $text .= "'$name' operator"; }
224 286         416 croak($text);
225             }
226              
227             sub _vectorize_
228             {
229 2671     2671   2364 my($vector,$scalar) = @_;
230              
231 2671 50       6448 if ($CONFIG[0] == 4) { $vector->from_Enum($scalar); }
  0 50       0  
    50          
    50          
232 0         0 elsif ($CONFIG[0] == 3) { $vector->from_Dec ($scalar); }
233 0         0 elsif ($CONFIG[0] == 2) { $vector->from_Bin ($scalar); }
234 0         0 elsif ($CONFIG[0] == 1) { $vector->from_Hex ($scalar); }
235 2671         5006 else { $vector->Bit_On ($scalar); }
236             }
237              
238             sub _scalarize_
239             {
240 0     0   0 my($vector) = @_;
241              
242 0 0       0 if ($CONFIG[2] == 3) { return( $vector->to_Enum() ); }
  0 0       0  
    0          
243 0         0 elsif ($CONFIG[2] == 2) { return( $vector->to_Dec () ); }
244 0         0 elsif ($CONFIG[2] == 1) { return( $vector->to_Bin () ); }
245 0         0 else { return( $vector->to_Hex () ); }
246             }
247              
248             sub _fetch_operand
249             {
250 2987     2987   2795 my($object,$argument,$flag,$name,$build) = @_;
251 2987         1877 my($operand);
252              
253 2987 100 66     16840 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
    100 100        
      66        
254             {
255             eval
256 96         89 {
257 96 100 100     184 if ($build && (defined $flag))
258             {
259 24         65 $operand = $argument->Clone();
260             }
261 72         59 else { $operand = $argument; }
262             };
263 96 50       130 if ($@) { &_error($name,0); }
  0         0  
264             }
265             elsif ((defined $argument) && (!ref($argument)))
266             {
267             eval
268 2671         2322 {
269 2671         6871 $operand = $object->Shadow();
270 2671         3242 &_vectorize_($operand,$argument);
271             };
272 2671 50       3614 if ($@) { &_error($name,0); }
  0         0  
273             }
274 220         246 else { &_error($name,1); }
275 2767         2634 return($operand);
276             }
277              
278             sub _check_operand
279             {
280 10355     10355   7489 my($argument,$flag,$name) = @_;
281              
282 10355 100 66     25936 if ((defined $argument) && (!ref($argument)))
283             {
284 10310 100 100     20194 if ((defined $flag) && $flag) { &_error($name,2); }
  6         12  
285             }
286 45         49 else { &_error($name,1); }
287             }
288              
289             sub _stringify
290             {
291 0     0   0 my($vector) = @_;
292 0         0 my($name) = 'string interpolation';
293 0         0 my($result);
294              
295             eval
296 0         0 {
297 0         0 $result = &_scalarize_($vector);
298             };
299 0 0       0 if ($@) { &_error($name,0); }
  0         0  
300 0         0 return($result);
301             }
302              
303             sub _boolean
304             {
305 29     29   211 my($object) = @_;
306 29         22 my($name) = 'boolean test';
307 29         20 my($result);
308              
309             eval
310 29         21 {
311 29         65 $result = $object->is_empty();
312             };
313 29 50       36 if ($@) { &_error($name,0); }
  0         0  
314 29         46 return(! $result);
315             }
316              
317             sub _not_boolean
318             {
319 7     7   87 my($object) = @_;
320 7         9 my($name) = 'negated boolean test';
321 7         6 my($result);
322              
323             eval
324 7         5 {
325 7         19 $result = $object->is_empty();
326             };
327 7 50       24 if ($@) { &_error($name,0); }
  0         0  
328 7         11 return($result);
329             }
330              
331             sub _complement
332             {
333 3     3   4 my($object) = @_;
334 3         3 my($name) = '~';
335 3         3 my($result);
336              
337             eval
338 3         3 {
339 3         6 $result = $object->Shadow();
340 3         10 $result->Complement($object);
341             };
342 3 50       6 if ($@) { &_error($name,0); }
  0         0  
343 3         5 return($result);
344             }
345              
346             sub _negate
347             {
348 0     0   0 my($object) = @_;
349 0         0 my($name) = 'unary minus';
350 0         0 my($result);
351              
352             eval
353 0         0 {
354 0         0 $result = $object->Shadow();
355 0         0 $result->Negate($object);
356             };
357 0 0       0 if ($@) { &_error($name,0); }
  0         0  
358 0         0 return($result);
359             }
360              
361             sub _absolute
362             {
363 41     41   249 my($object) = @_;
364 41         39 my($name) = 'abs()';
365 41         32 my($result);
366              
367             eval
368 41         28 {
369 41 50       51 if ($CONFIG[1] == 1)
370             {
371 0         0 $result = $object->Shadow();
372 0         0 $result->Absolute($object);
373             }
374             else
375             {
376 41         98 $result = $object->Norm();
377             }
378             };
379 41 50       53 if ($@) { &_error($name,0); }
  0         0  
380 41         66 return($result);
381             }
382              
383             sub _concat
384             {
385 15     15   730 my($object,$argument,$flag) = @_;
386 15         14 my($name) = '.';
387 15         13 my($result);
388              
389 15 100       24 $name .= '=' unless (defined $flag);
390 15 50 33     123 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
    50 33        
      33        
391             {
392             eval
393 0         0 {
394 0 0       0 if (defined $flag)
395             {
396 0 0       0 if ($flag) { $result = $argument->Concat($object); }
  0         0  
397 0         0 else { $result = $object->Concat($argument); }
398             }
399             else
400             {
401 0         0 $object->Interval_Substitute($argument,0,0,0,$argument->Size());
402 0         0 $result = $object;
403             }
404             };
405 0 0       0 if ($@) { &_error($name,0); }
  0         0  
406 0         0 return($result);
407             }
408             elsif ((defined $argument) && (!ref($argument)))
409             {
410             eval
411 0         0 {
412 0 0       0 if (defined $flag)
413             {
414 0 0       0 if ($flag) { $result = $argument . &_scalarize_($object); }
  0         0  
415 0         0 else { $result = &_scalarize_($object) . $argument; }
416             }
417             else
418             {
419 0 0       0 if ($CONFIG[0] == 2) { $result = $object->new( length($argument) ); }
  0 0       0  
420 0         0 elsif ($CONFIG[0] == 1) { $result = $object->new( length($argument) << 2 ); }
421 0         0 else { $result = $object->Shadow(); }
422 0         0 &_vectorize_($result,$argument);
423 0         0 $object->Interval_Substitute($result,0,0,0,$result->Size());
424 0         0 $result = $object;
425             }
426             };
427 0 0       0 if ($@) { &_error($name,0); }
  0         0  
428 0         0 return($result);
429             }
430 15         19 else { &_error($name,1); }
431             }
432              
433             sub _xerox # (in Brazil, a photocopy is called a "xerox")
434             {
435 17     17   868 my($object,$argument,$flag) = @_;
436 17         20 my($name) = 'x';
437 17         11 my($result);
438             my($offset);
439 0         0 my($index);
440 0         0 my($size);
441              
442 17 100       27 $name .= '=' unless (defined $flag);
443 17         20 &_check_operand($argument,$flag,$name);
444             eval
445 0         0 {
446 0         0 $size = $object->Size();
447 0 0       0 if (defined $flag)
448             {
449 0         0 $result = $object->new($size * $argument);
450 0         0 $offset = 0;
451 0         0 $index = 0;
452             }
453             else
454             {
455 0         0 $result = $object;
456 0         0 $result->Resize($size * $argument);
457 0         0 $offset = $size;
458 0         0 $index = 1;
459             }
460 0         0 for ( ; $index < $argument; $index++, $offset += $size )
461             {
462 0         0 $result->Interval_Copy($object,$offset,0,$size);
463             }
464             };
465 0 0       0 if ($@) { &_error($name,0); }
  0         0  
466 0         0 return($result);
467             }
468              
469             sub _shift_left
470             {
471 5169     5169   78118 my($object,$argument,$flag) = @_;
472 5169         3783 my($name) = '<<';
473 5169         3096 my($result);
474              
475 5169 100       6852 $name .= '=' unless (defined $flag);
476 5169         4834 &_check_operand($argument,$flag,$name);
477             eval
478 5152         3638 {
479 5152 100       4787 if (defined $flag)
480             {
481 2576         5447 $result = $object->Clone();
482 2576         6168 $result->Insert(0,$argument);
483             # $result->Move_Left($argument);
484             }
485             else
486             {
487             # $object->Move_Left($argument);
488 2576         5387 $object->Insert(0,$argument);
489 2576         2027 $result = $object;
490             }
491             };
492 5152 50       6036 if ($@) { &_error($name,0); }
  0         0  
493 5152         6269 return($result);
494             }
495              
496             sub _shift_right
497             {
498 5169     5169   318653 my($object,$argument,$flag) = @_;
499 5169         4139 my($name) = '>>';
500 5169         2965 my($result);
501              
502 5169 100       6844 $name .= '=' unless (defined $flag);
503 5169         4611 &_check_operand($argument,$flag,$name);
504             eval
505 5152         3769 {
506 5152 100       4743 if (defined $flag)
507             {
508 2576         5222 $result = $object->Clone();
509 2576         5520 $result->Delete(0,$argument);
510             # $result->Move_Right($argument);
511             }
512             else
513             {
514             # $object->Move_Right($argument);
515 2576         5197 $object->Delete(0,$argument);
516 2576         2055 $result = $object;
517             }
518             };
519 5152 50       5977 if ($@) { &_error($name,0); }
  0         0  
520 5152         6526 return($result);
521             }
522              
523             sub _union_
524             {
525 1021     1021   1032 my($object,$operand,$flag) = @_;
526              
527 1021 100       1261 if (defined $flag)
528             {
529 13         28 $operand->Union($object,$operand);
530 13         13 return($operand);
531             }
532             else
533             {
534 1008         2296 $object->Union($object,$operand);
535 1008         1437 return($object);
536             }
537             }
538              
539             sub _union
540             {
541 19     19   768 my($object,$argument,$flag) = @_;
542 19         18 my($name) = '|';
543 19         12 my($operand);
544              
545 19 100       32 $name .= '=' unless (defined $flag);
546 19         20 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
547             eval
548 4         4 {
549 4         5 $operand = &_union_($object,$operand,$flag);
550             };
551 4 50       8 if ($@) { &_error($name,0); }
  0         0  
552 4         7 return($operand);
553             }
554              
555             sub _intersection_
556             {
557 15     15   15 my($object,$operand,$flag) = @_;
558              
559 15 100       19 if (defined $flag)
560             {
561 11         25 $operand->Intersection($object,$operand);
562 11         13 return($operand);
563             }
564             else
565             {
566 4         6 $object->Intersection($object,$operand);
567 4         5 return($object);
568             }
569             }
570              
571             sub _intersection
572             {
573 19     19   792 my($object,$argument,$flag) = @_;
574 19         16 my($name) = '&';
575 19         9 my($operand);
576              
577 19 100       40 $name .= '=' unless (defined $flag);
578 19         22 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
579             eval
580 4         3 {
581 4         5 $operand = &_intersection_($object,$operand,$flag);
582             };
583 4 50       6 if ($@) { &_error($name,0); }
  0         0  
584 4         6 return($operand);
585             }
586              
587             sub _exclusive_or
588             {
589 24     24   787 my($object,$argument,$flag) = @_;
590 24         24 my($name) = '^';
591 24         17 my($operand);
592              
593 24 100       36 $name .= '=' unless (defined $flag);
594 24         28 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
595             eval
596 9         7 {
597 9 100       12 if (defined $flag)
598             {
599 3         11 $operand->ExclusiveOr($object,$operand);
600             }
601             else
602             {
603 6         16 $object->ExclusiveOr($object,$operand);
604 6         6 $operand = $object;
605             }
606             };
607 9 50       21 if ($@) { &_error($name,0); }
  0         0  
608 9         16 return($operand);
609             }
610              
611             sub _add
612             {
613 1032     1032   1679 my($object,$argument,$flag) = @_;
614 1032         1094 my($name) = '+';
615 1032         741 my($operand);
616              
617 1032 100       1793 $name .= '=' unless (defined $flag);
618 1032         1299 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
619             eval
620 1017         915 {
621 1017 50       1232 if ($CONFIG[1] == 1)
622             {
623 0 0       0 if (defined $flag)
624             {
625 0         0 $operand->add($object,$operand,0);
626             }
627             else
628             {
629 0         0 $object->add($object,$operand,0);
630 0         0 $operand = $object;
631             }
632             }
633             else
634             {
635 1017         1167 $operand = &_union_($object,$operand,$flag);
636             }
637             };
638 1017 50       3310 if ($@) { &_error($name,0); }
  0         0  
639 1017         2436 return($operand);
640             }
641              
642             sub _sub
643             {
644 1649     1649   2134 my($object,$argument,$flag) = @_;
645 1649         1363 my($name) = '-';
646 1649         1130 my($operand);
647              
648 1649 100       2478 $name .= '=' unless (defined $flag);
649 1649         1715 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
650             eval
651 1634         1273 {
652 1634 50       1714 if ($CONFIG[1] == 1)
653             {
654 0 0       0 if (defined $flag)
655             {
656 0 0       0 if ($flag) { $operand->subtract($operand,$object,0); }
  0         0  
657 0         0 else { $operand->subtract($object,$operand,0); }
658             }
659             else
660             {
661 0         0 $object->subtract($object,$operand,0);
662 0         0 $operand = $object;
663             }
664             }
665             else
666             {
667 1634 100       1668 if (defined $flag)
668             {
669 8 50       9 if ($flag) { $operand->Difference($operand,$object); }
  0         0  
670 8         25 else { $operand->Difference($object,$operand); }
671             }
672             else
673             {
674 1626         2779 $object->Difference($object,$operand);
675 1626         1347 $operand = $object;
676             }
677             }
678             };
679 1634 50       3821 if ($@) { &_error($name,0); }
  0         0  
680 1634         2980 return($operand);
681             }
682              
683             sub _mul
684             {
685 26     26   844 my($object,$argument,$flag) = @_;
686 26         28 my($name) = '*';
687 26         15 my($operand);
688              
689 26 100       40 $name .= '=' unless (defined $flag);
690 26         30 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
691             eval
692 11         12 {
693 11 50       12 if ($CONFIG[1] == 1)
694             {
695 0 0       0 if (defined $flag)
696             {
697 0         0 $operand->Multiply($object,$operand);
698             }
699             else
700             {
701 0         0 $object->Multiply($object,$operand);
702 0         0 $operand = $object;
703             }
704             }
705             else
706             {
707 11         51 $operand = &_intersection_($object,$operand,$flag);
708             }
709             };
710 11 50       16 if ($@) { &_error($name,0); }
  0         0  
711 11         24 return($operand);
712             }
713              
714             sub _div
715             {
716 0     0   0 my($object,$argument,$flag) = @_;
717 0         0 my($name) = '/';
718 0         0 my($operand);
719             my($temp);
720              
721 0 0       0 $name .= '=' unless (defined $flag);
722 0         0 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
723             eval
724 0         0 {
725 0         0 $temp = $object->Shadow();
726 0 0       0 if (defined $flag)
727             {
728 0 0       0 if ($flag) { $operand->Divide($operand,$object,$temp); }
  0         0  
729 0         0 else { $operand->Divide($object,$operand,$temp); }
730             }
731             else
732             {
733 0         0 $object->Divide($object,$operand,$temp);
734 0         0 $operand = $object;
735             }
736             };
737 0 0       0 if ($@) { &_error($name,0); }
  0         0  
738 0         0 return($operand);
739             }
740              
741             sub _mod
742             {
743 0     0   0 my($object,$argument,$flag) = @_;
744 0         0 my($name) = '%';
745 0         0 my($operand);
746             my($temp);
747              
748 0 0       0 $name .= '=' unless (defined $flag);
749 0         0 $operand = &_fetch_operand($object,$argument,$flag,$name,1);
750             eval
751 0         0 {
752 0         0 $temp = $object->Shadow();
753 0 0       0 if (defined $flag)
754             {
755 0 0       0 if ($flag) { $temp->Divide($operand,$object,$operand); }
  0         0  
756 0         0 else { $temp->Divide($object,$operand,$operand); }
757             }
758             else
759             {
760 0         0 $temp->Divide($object,$operand,$object);
761 0         0 $operand = $object;
762             }
763             };
764 0 0       0 if ($@) { &_error($name,0); }
  0         0  
765 0         0 return($operand);
766             }
767              
768             sub _pow
769             {
770 0     0   0 my($object,$argument,$flag) = @_;
771 0         0 my($name) = '**';
772 0         0 my($operand,$result);
773              
774 0 0       0 $name .= '=' unless (defined $flag);
775 0         0 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
776             eval
777 0         0 {
778 0 0       0 if (defined $flag)
779             {
780 0         0 $result = $object->Shadow();
781 0 0       0 if ($flag) { $result->Power($operand,$object); }
  0         0  
782 0         0 else { $result->Power($object,$operand); }
783             }
784             else
785             {
786 0         0 $object->Power($object,$operand);
787 0         0 $result = $object;
788             }
789             };
790 0 0       0 if ($@) { &_error($name,0); }
  0         0  
791 0         0 return($result);
792             }
793              
794             sub _assign_concat
795             {
796 5     5   704 my($object,$argument) = @_;
797              
798 5         8 return( &_concat($object,$argument,undef) );
799             }
800              
801             sub _assign_xerox
802             {
803 5     5   413 my($object,$argument) = @_;
804              
805 5         6 return( &_xerox($object,$argument,undef) );
806             }
807              
808             sub _assign_shift_left
809             {
810 2581     2581   616450 my($object,$argument) = @_;
811              
812 2581         2781 return( &_shift_left($object,$argument,undef) );
813             }
814              
815             sub _assign_shift_right
816             {
817 2581     2581   92039 my($object,$argument) = @_;
818              
819 2581         2656 return( &_shift_right($object,$argument,undef) );
820             }
821              
822             sub _assign_union
823             {
824 7     7   417 my($object,$argument) = @_;
825              
826 7         11 return( &_union($object,$argument,undef) );
827             }
828              
829             sub _assign_intersection
830             {
831 7     7   427 my($object,$argument) = @_;
832              
833 7         12 return( &_intersection($object,$argument,undef) );
834             }
835              
836             sub _assign_exclusive_or
837             {
838 11     11   470 my($object,$argument) = @_;
839              
840 11         18 return( &_exclusive_or($object,$argument,undef) );
841             }
842              
843             sub _assign_add
844             {
845 1011     1011   3238 my($object,$argument) = @_;
846              
847 1011         1196 return( &_add($object,$argument,undef) );
848             }
849              
850             sub _assign_sub
851             {
852 1631     1631   4147 my($object,$argument) = @_;
853              
854 1631         1699 return( &_sub($object,$argument,undef) );
855             }
856              
857             sub _assign_mul
858             {
859 7     7   434 my($object,$argument) = @_;
860              
861 7         10 return( &_mul($object,$argument,undef) );
862             }
863              
864             sub _assign_div
865             {
866 0     0   0 my($object,$argument) = @_;
867              
868 0         0 return( &_div($object,$argument,undef) );
869             }
870              
871             sub _assign_mod
872             {
873 0     0   0 my($object,$argument) = @_;
874              
875 0         0 return( &_mod($object,$argument,undef) );
876             }
877              
878             sub _assign_pow
879             {
880 0     0   0 my($object,$argument) = @_;
881              
882 0         0 return( &_pow($object,$argument,undef) );
883             }
884              
885             sub _increment
886             {
887 8     8   33 my($object) = @_;
888 8         7 my($name) = '++';
889 8         5 my($result);
890              
891             eval
892 8         6 {
893 8         25 $result = $object->increment();
894             };
895 8 50       10 if ($@) { &_error($name,0); }
  0         0  
896 8         14 return($result);
897             }
898              
899             sub _decrement
900             {
901 8     8   32 my($object) = @_;
902 8         6 my($name) = '--';
903 8         5 my($result);
904              
905             eval
906 8         6 {
907 8         12 $result = $object->decrement();
908             };
909 8 50       12 if ($@) { &_error($name,0); }
  0         0  
910 8         12 return($result);
911             }
912              
913             sub _lexicompare
914             {
915 91     91   5617 my($object,$argument,$flag) = @_;
916 91         80 my($name) = 'cmp';
917 91         54 my($operand);
918             my($result);
919              
920 91         99 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
921             eval
922 21         13 {
923 21 100 66     49 if ((defined $flag) && $flag)
924             {
925 1         3 $result = $operand->Lexicompare($object);
926             }
927             else
928             {
929 20         38 $result = $object->Lexicompare($operand);
930             }
931             };
932 21 50       22 if ($@) { &_error($name,0); }
  0         0  
933 21         33 return($result);
934             }
935              
936             sub _compare
937             {
938 0     0   0 my($object,$argument,$flag) = @_;
939 0         0 my($name) = '<=>';
940 0         0 my($operand);
941             my($result);
942              
943 0         0 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
944             eval
945 0         0 {
946 0 0 0     0 if ((defined $flag) && $flag)
947             {
948 0         0 $result = $operand->Compare($object);
949             }
950             else
951             {
952 0         0 $result = $object->Compare($operand);
953             }
954             };
955 0 0       0 if ($@) { &_error($name,0); }
  0         0  
956 0         0 return($result);
957             }
958              
959             sub _equal
960             {
961 50     50   974 my($object,$argument,$flag) = @_;
962 50         44 my($name) = '==';
963 50         38 my($operand);
964             my($result);
965              
966 50         54 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
967             eval
968 40         27 {
969 40         78 $result = $object->equal($operand);
970             };
971 40 50       47 if ($@) { &_error($name,0); }
  0         0  
972 40         74 return($result);
973             }
974              
975             sub _not_equal
976             {
977 13     13   766 my($object,$argument,$flag) = @_;
978 13         14 my($name) = '!=';
979 13         8 my($operand);
980             my($result);
981              
982 13         17 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
983             eval
984 3         4 {
985 3         9 $result = $object->equal($operand);
986             };
987 3 50       5 if ($@) { &_error($name,0); }
  0         0  
988 3         9 return(! $result);
989             }
990              
991             sub _less_than
992             {
993 16     16   796 my($object,$argument,$flag) = @_;
994 16         17 my($name) = '<';
995 16         12 my($operand);
996             my($result);
997              
998 16         19 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
999             eval
1000 6         9 {
1001 6 50       10 if ($CONFIG[1] == 1)
1002             {
1003 0 0 0     0 if ((defined $flag) && $flag)
1004             {
1005 0         0 $result = ($operand->Compare($object) < 0);
1006             }
1007             else
1008             {
1009 0         0 $result = ($object->Compare($operand) < 0);
1010             }
1011             }
1012             else
1013             {
1014 6 100 66     24 if ((defined $flag) && $flag)
1015             {
1016 1   33     11 $result = ((!$operand->equal($object)) &&
1017             ($operand->subset($object)));
1018             }
1019             else
1020             {
1021 5   66     39 $result = ((!$object->equal($operand)) &&
1022             ($object->subset($operand)));
1023             }
1024             }
1025             };
1026 6 50       9 if ($@) { &_error($name,0); }
  0         0  
1027 6         21 return($result);
1028             }
1029              
1030             sub _less_equal
1031             {
1032 16     16   792 my($object,$argument,$flag) = @_;
1033 16         17 my($name) = '<=';
1034 16         11 my($operand);
1035             my($result);
1036              
1037 16         21 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
1038             eval
1039 6         6 {
1040 6 50       11 if ($CONFIG[1] == 1)
1041             {
1042 0 0 0     0 if ((defined $flag) && $flag)
1043             {
1044 0         0 $result = ($operand->Compare($object) <= 0);
1045             }
1046             else
1047             {
1048 0         0 $result = ($object->Compare($operand) <= 0);
1049             }
1050             }
1051             else
1052             {
1053 6 100 66     23 if ((defined $flag) && $flag)
1054             {
1055 1         5 $result = $operand->subset($object);
1056             }
1057             else
1058             {
1059 5         16 $result = $object->subset($operand);
1060             }
1061             }
1062             };
1063 6 50       11 if ($@) { &_error($name,0); }
  0         0  
1064 6         17 return($result);
1065             }
1066              
1067             sub _greater_than
1068             {
1069 16     16   803 my($object,$argument,$flag) = @_;
1070 16         20 my($name) = '>';
1071 16         15 my($operand);
1072             my($result);
1073              
1074 16         19 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
1075             eval
1076 6         8 {
1077 6 50       8 if ($CONFIG[1] == 1)
1078             {
1079 0 0 0     0 if ((defined $flag) && $flag)
1080             {
1081 0         0 $result = ($operand->Compare($object) > 0);
1082             }
1083             else
1084             {
1085 0         0 $result = ($object->Compare($operand) > 0);
1086             }
1087             }
1088             else
1089             {
1090 6 100 66     21 if ((defined $flag) && $flag)
1091             {
1092 1   33     10 $result = ((!$object->equal($operand)) &&
1093             ($object->subset($operand)));
1094             }
1095             else
1096             {
1097 5   66     35 $result = ((!$operand->equal($object)) &&
1098             ($operand->subset($object)));
1099             }
1100             }
1101             };
1102 6 50       10 if ($@) { &_error($name,0); }
  0         0  
1103 6         19 return($result);
1104             }
1105              
1106             sub _greater_equal
1107             {
1108 16     16   832 my($object,$argument,$flag) = @_;
1109 16         14 my($name) = '>=';
1110 16         15 my($operand);
1111             my($result);
1112              
1113 16         20 $operand = &_fetch_operand($object,$argument,$flag,$name,0);
1114             eval
1115 6         6 {
1116 6 50       10 if ($CONFIG[1] == 1)
1117             {
1118 0 0 0     0 if ((defined $flag) && $flag)
1119             {
1120 0         0 $result = ($operand->Compare($object) >= 0);
1121             }
1122             else
1123             {
1124 0         0 $result = ($object->Compare($operand) >= 0);
1125             }
1126             }
1127             else
1128             {
1129 6 100 66     29 if ((defined $flag) && $flag)
1130             {
1131 1         10 $result = $object->subset($operand);
1132             }
1133             else
1134             {
1135 5         13 $result = $operand->subset($object);
1136             }
1137             }
1138             };
1139 6 50       12 if ($@) { &_error($name,0); }
  0         0  
1140 6         20 return($result);
1141             }
1142              
1143             sub _clone
1144             {
1145 5     5   45 my($object) = @_;
1146 5         5 my($name) = 'automatic duplication';
1147 5         6 my($result);
1148              
1149             eval
1150 5         4 {
1151 5         13 $result = $object->Clone();
1152             };
1153 5 50       9 if ($@) { &_error($name,0); }
  0         0  
1154 5         7 return($result);
1155             }
1156              
1157             1;
1158              
1159             __END__