OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / lib / bitvector / Vector.xs
1
2
3 /*****************************************************************************/
4 /*                                                                           */
5 /*    Copyright (c) 1995 - 2004 by Steffen Beyer.                            */
6 /*    All rights reserved.                                                   */
7 /*                                                                           */
8 /*    This package is free software; you can redistribute it                 */
9 /*    and/or modify it under the same terms as Perl itself.                  */
10 /*                                                                           */
11 /*****************************************************************************/
12
13
14 #include "EXTERN.h"
15 #include "perl.h"
16 #include "XSUB.h"
17
18
19 #include "patchlevel.h"
20 #if ((PATCHLEVEL < 4) || ((PATCHLEVEL == 4) && (SUBVERSION < 5)))
21 /* PL_na was introduced in perl5.004_05 */
22 #ifndef PL_na
23     #define PL_na na
24 #endif
25 #endif
26 #if (PATCHLEVEL < 4)
27 /* GIMME_V was introduced in perl5.004 */
28 #ifndef GIMME_V
29     #define GIMME_V GIMME
30 #endif
31 #endif
32
33
34 #include "BitVector.h"
35
36
37 static    char *BitVector_Class = "Bit::Vector";
38 static      HV *BitVector_Stash;
39
40 typedef     SV *BitVector_Object;
41 typedef     SV *BitVector_Handle;
42 typedef N_word *BitVector_Address;
43 typedef     SV *BitVector_Scalar;
44
45
46 const char *BitVector_OBJECT_ERROR = "item is not a \"Bit::Vector\" object";
47 const char *BitVector_SCALAR_ERROR = "item is not a scalar";
48 const char *BitVector_STRING_ERROR = "item is not a string";
49 const char *BitVector_MIN_ERROR    = "minimum index out of range";
50 const char *BitVector_MAX_ERROR    = "maximum index out of range";
51 const char *BitVector_START_ERROR  = "start index out of range";
52 const char *BitVector_OFFSET_ERROR = "offset out of range";
53 const char *BitVector_CHUNK_ERROR  = "chunk size out of range";
54 const char *BitVector_SET_ERROR    = "set size mismatch";
55 const char *BitVector_MATRIX_ERROR = "matrix size mismatch";
56 const char *BitVector_SHAPE_ERROR  = "not a square matrix";
57 const char *BitVector_MEMORY_ERROR = ERRCODE_NULL;
58 const char *BitVector_INDEX_ERROR  = ERRCODE_INDX;
59 const char *BitVector_ORDER_ERROR  = ERRCODE_ORDR;
60 const char *BitVector_SIZE_ERROR   = ERRCODE_SIZE;
61
62
63 #define BIT_VECTOR_OBJECT(ref,hdl,adr) \
64     ( ref && \
65     SvROK(ref) && \
66     (hdl = (BitVector_Handle)SvRV(ref)) && \
67     SvOBJECT(hdl) && \
68     SvREADONLY(hdl) && \
69     (SvTYPE(hdl) == SVt_PVMG) && \
70     (SvSTASH(hdl) == BitVector_Stash) && \
71     (adr = (BitVector_Address)SvIV(hdl)) )
72
73 #define BIT_VECTOR_SCALAR(ref,typ,var) \
74     ( ref && !(SvROK(ref)) && ((var = (typ)SvIV(ref)) | 1) )
75
76 #define BIT_VECTOR_STRING(ref,var) \
77     ( ref && !(SvROK(ref)) && (var = (charptr)SvPV(ref,PL_na)) )
78
79 #define BIT_VECTOR_BUFFER(ref,var,len) \
80     ( ref && !(SvROK(ref)) && SvPOK(ref) && \
81     (var = (charptr)SvPV(ref,PL_na)) && \
82     ((len = (N_int)SvCUR(ref)) | 1) )
83
84
85 #define BIT_VECTOR_ERROR(message) \
86     croak("Bit::Vector::%s(): %s", GvNAME(CvGV(cv)), message)
87
88
89 #define BIT_VECTOR_OBJECT_ERROR \
90     BIT_VECTOR_ERROR( BitVector_OBJECT_ERROR )
91
92 #define BIT_VECTOR_SCALAR_ERROR \
93     BIT_VECTOR_ERROR( BitVector_SCALAR_ERROR )
94
95 #define BIT_VECTOR_STRING_ERROR \
96     BIT_VECTOR_ERROR( BitVector_STRING_ERROR )
97
98 #define BIT_VECTOR_MIN_ERROR \
99     BIT_VECTOR_ERROR( BitVector_MIN_ERROR )
100
101 #define BIT_VECTOR_MAX_ERROR \
102     BIT_VECTOR_ERROR( BitVector_MAX_ERROR )
103
104 #define BIT_VECTOR_START_ERROR \
105     BIT_VECTOR_ERROR( BitVector_START_ERROR )
106
107 #define BIT_VECTOR_OFFSET_ERROR \
108     BIT_VECTOR_ERROR( BitVector_OFFSET_ERROR )
109
110 #define BIT_VECTOR_CHUNK_ERROR \
111     BIT_VECTOR_ERROR( BitVector_CHUNK_ERROR )
112
113 #define BIT_VECTOR_SET_ERROR \
114     BIT_VECTOR_ERROR( BitVector_SET_ERROR )
115
116 #define BIT_VECTOR_MATRIX_ERROR \
117     BIT_VECTOR_ERROR( BitVector_MATRIX_ERROR )
118
119 #define BIT_VECTOR_SHAPE_ERROR \
120     BIT_VECTOR_ERROR( BitVector_SHAPE_ERROR )
121
122 #define BIT_VECTOR_MEMORY_ERROR \
123     BIT_VECTOR_ERROR( BitVector_MEMORY_ERROR )
124
125 #define BIT_VECTOR_INDEX_ERROR \
126     BIT_VECTOR_ERROR( BitVector_INDEX_ERROR )
127
128 #define BIT_VECTOR_ORDER_ERROR \
129     BIT_VECTOR_ERROR( BitVector_ORDER_ERROR )
130
131 #define BIT_VECTOR_SIZE_ERROR \
132     BIT_VECTOR_ERROR( BitVector_SIZE_ERROR )
133
134
135 #define BIT_VECTOR_EXCEPTION(code) \
136     BIT_VECTOR_ERROR( BitVector_Error(code) )
137
138
139 MODULE = Bit::Vector            PACKAGE = Bit::Vector           PREFIX = BitVector_
140
141
142 PROTOTYPES: DISABLE
143
144
145 BOOT:
146 {
147     ErrCode rc;
148
149     if ((rc = BitVector_Boot()))
150     {
151         BIT_VECTOR_EXCEPTION(rc);
152         exit((int)rc);
153     }
154     BitVector_Stash = gv_stashpv(BitVector_Class,1);
155 }
156
157
158 void
159 BitVector_Version(...)
160 PPCODE:
161 {
162     charptr string;
163
164     if ((items >= 0) and (items <= 1))
165     {
166         string = BitVector_Version();
167         if (string != NULL)
168         {
169             EXTEND(sp,1);
170             PUSHs(sv_2mortal(newSVpv((char *)string,0)));
171         }
172         else BIT_VECTOR_MEMORY_ERROR;
173     }
174     else croak("Usage: Bit::Vector->Version()");
175 }
176
177
178 N_int
179 BitVector_Word_Bits(...)
180 CODE:
181 {
182     if ((items >= 0) and (items <= 1))
183     {
184         RETVAL = BitVector_Word_Bits();
185     }
186     else croak("Usage: Bit::Vector->Word_Bits()");
187 }
188 OUTPUT:
189 RETVAL
190
191
192 N_int
193 BitVector_Long_Bits(...)
194 CODE:
195 {
196     if ((items >= 0) and (items <= 1))
197     {
198         RETVAL = BitVector_Long_Bits();
199     }
200     else croak("Usage: Bit::Vector->Long_Bits()");
201 }
202 OUTPUT:
203 RETVAL
204
205
206 void
207 BitVector_Create(...)
208 ALIAS:
209   new = 1
210 PPCODE:
211 {
212     BitVector_Scalar  arg1;
213     BitVector_Scalar  arg2;
214     BitVector_Address address;
215     BitVector_Handle  handle;
216     BitVector_Object  reference;
217     listptr list;
218     listptr slot;
219     N_int bits;
220     N_int count;
221
222     if ((items >= 2) and (items <= 3))
223     {
224         arg1 = ST(1);
225         if ( BIT_VECTOR_SCALAR(arg1,N_int,bits) )
226         {
227             if (items > 2)
228             {
229                 arg2 = ST(2);
230                 if ( BIT_VECTOR_SCALAR(arg2,N_int,count) )
231                 {
232                     if (count > 0)
233                     {
234                         if ((list = BitVector_Create_List(bits,true,count)) != NULL)
235                         {
236                             EXTEND(sp,(int)count);
237                             slot = list;
238                             while (count-- > 0)
239                             {
240                                 address = *slot++;
241                                 handle = newSViv((IV)address);
242                                 reference = sv_bless(sv_2mortal(newRV(handle)),
243                                     BitVector_Stash);
244                                 SvREFCNT_dec(handle);
245                                 SvREADONLY_on(handle);
246                                 PUSHs(reference);
247                             }
248                             BitVector_Destroy_List(list,0);
249                         }
250                         else BIT_VECTOR_MEMORY_ERROR;
251                     }
252                 }
253                 else BIT_VECTOR_SCALAR_ERROR;
254             }
255             else
256             {
257                 if ((address = BitVector_Create(bits,true)) != NULL)
258                 {
259                     handle = newSViv((IV)address);
260                     reference = sv_bless(sv_2mortal(newRV(handle)),
261                         BitVector_Stash);
262                     SvREFCNT_dec(handle);
263                     SvREADONLY_on(handle);
264                     PUSHs(reference);
265                 }
266                 else BIT_VECTOR_MEMORY_ERROR;
267             }
268         }
269         else BIT_VECTOR_SCALAR_ERROR;
270     }
271     else croak("Usage: %s(class,bits[,count])", GvNAME(CvGV(cv)));
272 }
273
274
275 void
276 BitVector_new_Hex(class,bits,string)
277 BitVector_Object        class
278 BitVector_Scalar        bits
279 BitVector_Scalar        string
280 PPCODE:
281 {
282     BitVector_Address address;
283     BitVector_Handle  handle;
284     BitVector_Object  reference;
285     N_int   size;
286     charptr pointer;
287     ErrCode code;
288
289     if ( BIT_VECTOR_SCALAR(bits,N_int,size) )
290     {
291         if ( BIT_VECTOR_STRING(string,pointer) )
292         {
293             if ((address = BitVector_Create(size,false)) != NULL)
294             {
295                 if ((code = BitVector_from_Hex(address,pointer)))
296                 {
297                     BitVector_Destroy(address);
298                     BIT_VECTOR_EXCEPTION(code);
299                 }
300                 else
301                 {
302                     handle = newSViv((IV)address);
303                     reference = sv_bless(sv_2mortal(newRV(handle)),
304                         BitVector_Stash);
305                     SvREFCNT_dec(handle);
306                     SvREADONLY_on(handle);
307                     PUSHs(reference);
308                 }
309             }
310             else BIT_VECTOR_MEMORY_ERROR;
311         }
312         else BIT_VECTOR_STRING_ERROR;
313     }
314     else BIT_VECTOR_SCALAR_ERROR;
315 }
316
317
318 void
319 BitVector_new_Bin(class,bits,string)
320 BitVector_Object        class
321 BitVector_Scalar        bits
322 BitVector_Scalar        string
323 PPCODE:
324 {
325     BitVector_Address address;
326     BitVector_Handle  handle;
327     BitVector_Object  reference;
328     N_int   size;
329     charptr pointer;
330     ErrCode code;
331
332     if ( BIT_VECTOR_SCALAR(bits,N_int,size) )
333     {
334         if ( BIT_VECTOR_STRING(string,pointer) )
335         {
336             if ((address = BitVector_Create(size,false)) != NULL)
337             {
338                 if ((code = BitVector_from_Bin(address,pointer)))
339                 {
340                     BitVector_Destroy(address);
341                     BIT_VECTOR_EXCEPTION(code);
342                 }
343                 else
344                 {
345                     handle = newSViv((IV)address);
346                     reference = sv_bless(sv_2mortal(newRV(handle)),
347                         BitVector_Stash);
348                     SvREFCNT_dec(handle);
349                     SvREADONLY_on(handle);
350                     PUSHs(reference);
351                 }
352             }
353             else BIT_VECTOR_MEMORY_ERROR;
354         }
355         else BIT_VECTOR_STRING_ERROR;
356     }
357     else BIT_VECTOR_SCALAR_ERROR;
358 }
359
360
361 void
362 BitVector_new_Dec(class,bits,string)
363 BitVector_Object        class
364 BitVector_Scalar        bits
365 BitVector_Scalar        string
366 PPCODE:
367 {
368     BitVector_Address address;
369     BitVector_Handle  handle;
370     BitVector_Object  reference;
371     N_int   size;
372     charptr pointer;
373     ErrCode code;
374
375     if ( BIT_VECTOR_SCALAR(bits,N_int,size) )
376     {
377         if ( BIT_VECTOR_STRING(string,pointer) )
378         {
379             if ((address = BitVector_Create(size,false)) != NULL)
380             {
381                 if ((code = BitVector_from_Dec(address,pointer)))
382                 {
383                     BitVector_Destroy(address);
384                     BIT_VECTOR_EXCEPTION(code);
385                 }
386                 else
387                 {
388                     handle = newSViv((IV)address);
389                     reference = sv_bless(sv_2mortal(newRV(handle)),
390                         BitVector_Stash);
391                     SvREFCNT_dec(handle);
392                     SvREADONLY_on(handle);
393                     PUSHs(reference);
394                 }
395             }
396             else BIT_VECTOR_MEMORY_ERROR;
397         }
398         else BIT_VECTOR_STRING_ERROR;
399     }
400     else BIT_VECTOR_SCALAR_ERROR;
401 }
402
403
404 void
405 BitVector_new_Enum(class,bits,string)
406 BitVector_Object        class
407 BitVector_Scalar        bits
408 BitVector_Scalar        string
409 PPCODE:
410 {
411     BitVector_Address address;
412     BitVector_Handle  handle;
413     BitVector_Object  reference;
414     N_int   size;
415     charptr pointer;
416     ErrCode code;
417
418     if ( BIT_VECTOR_SCALAR(bits,N_int,size) )
419     {
420         if ( BIT_VECTOR_STRING(string,pointer) )
421         {
422             if ((address = BitVector_Create(size,false)) != NULL)
423             {
424                 if ((code = BitVector_from_Enum(address,pointer)))
425                 {
426                     BitVector_Destroy(address);
427                     BIT_VECTOR_EXCEPTION(code);
428                 }
429                 else
430                 {
431                     handle = newSViv((IV)address);
432                     reference = sv_bless(sv_2mortal(newRV(handle)),
433                         BitVector_Stash);
434                     SvREFCNT_dec(handle);
435                     SvREADONLY_on(handle);
436                     PUSHs(reference);
437                 }
438             }
439             else BIT_VECTOR_MEMORY_ERROR;
440         }
441         else BIT_VECTOR_STRING_ERROR;
442     }
443     else BIT_VECTOR_SCALAR_ERROR;
444 }
445
446
447 void
448 BitVector_Shadow(reference)
449 BitVector_Object        reference
450 PPCODE:
451 {
452     BitVector_Handle  handle;
453     BitVector_Address address;
454
455     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
456     {
457         if ((address = BitVector_Shadow(address)) != NULL)
458         {
459             handle = newSViv((IV)address);
460             reference = sv_bless(sv_2mortal(newRV(handle)),
461                 BitVector_Stash);
462             SvREFCNT_dec(handle);
463             SvREADONLY_on(handle);
464             PUSHs(reference);
465         }
466         else BIT_VECTOR_MEMORY_ERROR;
467     }
468     else BIT_VECTOR_OBJECT_ERROR;
469 }
470
471
472 void
473 BitVector_Clone(reference)
474 BitVector_Object        reference
475 PPCODE:
476 {
477     BitVector_Handle  handle;
478     BitVector_Address address;
479
480     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
481     {
482         if ((address = BitVector_Clone(address)) != NULL)
483         {
484             handle = newSViv((IV)address);
485             reference = sv_bless(sv_2mortal(newRV(handle)),
486                 BitVector_Stash);
487             SvREFCNT_dec(handle);
488             SvREADONLY_on(handle);
489             PUSHs(reference);
490         }
491         else BIT_VECTOR_MEMORY_ERROR;
492     }
493     else BIT_VECTOR_OBJECT_ERROR;
494 }
495
496
497 void
498 BitVector_Concat(Xref,Yref)
499 BitVector_Object        Xref
500 BitVector_Object        Yref
501 PPCODE:
502 {
503     BitVector_Handle  Xhdl;
504     BitVector_Address Xadr;
505     BitVector_Handle  Yhdl;
506     BitVector_Address Yadr;
507     BitVector_Object  reference;
508     BitVector_Handle  handle;
509     BitVector_Address address;
510
511     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
512          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
513     {
514         if ((address = BitVector_Concat(Xadr,Yadr)) != NULL)
515         {
516             handle = newSViv((IV)address);
517             reference = sv_bless(sv_2mortal(newRV(handle)),
518                 BitVector_Stash);
519             SvREFCNT_dec(handle);
520             SvREADONLY_on(handle);
521             PUSHs(reference);
522         }
523         else BIT_VECTOR_MEMORY_ERROR;
524     }
525     else BIT_VECTOR_OBJECT_ERROR;
526 }
527
528
529 void
530 BitVector_Concat_List(...)
531 PPCODE:
532 {
533     BitVector_Object  Xref;
534     BitVector_Handle  Xhdl;
535     BitVector_Address Xadr;
536     BitVector_Object  reference;
537     BitVector_Handle  handle;
538     BitVector_Address address;
539     N_int offset;
540     N_int bits;
541     I32 index;
542
543     bits = 0;
544     index = items;
545     while (index-- > 0)
546     {
547         Xref = ST(index);
548         if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) )
549         {
550             bits += bits_(Xadr);
551         }
552         else if ((index != 0) or SvROK(Xref))
553           BIT_VECTOR_OBJECT_ERROR;
554     }
555     if ((address = BitVector_Create(bits,false)) != NULL)
556     {
557         offset = 0;
558         index = items;
559         while (index-- > 0)
560         {
561             Xref = ST(index);
562             if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) )
563             {
564                 if ((bits = bits_(Xadr)) > 0)
565                 {
566                     BitVector_Interval_Copy(address,Xadr,offset,0,bits);
567                     offset += bits;
568                 }
569             }
570             else if ((index != 0) or SvROK(Xref)) BIT_VECTOR_OBJECT_ERROR;
571         }
572         handle = newSViv((IV)address);
573         reference = sv_bless(sv_2mortal(newRV(handle)),
574             BitVector_Stash);
575         SvREFCNT_dec(handle);
576         SvREADONLY_on(handle);
577         PUSHs(reference);
578     }
579     else BIT_VECTOR_MEMORY_ERROR;
580 }
581
582
583 N_int
584 BitVector_Size(reference)
585 BitVector_Object        reference
586 CODE:
587 {
588     BitVector_Handle  handle;
589     BitVector_Address address;
590
591     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
592     {
593         RETVAL = bits_(address);
594     }
595     else BIT_VECTOR_OBJECT_ERROR;
596 }
597 OUTPUT:
598 RETVAL
599
600
601 void
602 BitVector_Resize(reference,bits)
603 BitVector_Object        reference
604 BitVector_Scalar        bits
605 CODE:
606 {
607     BitVector_Handle  handle;
608     BitVector_Address address;
609     N_int size;
610
611     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
612     {
613         if ( BIT_VECTOR_SCALAR(bits,N_int,size) )
614         {
615             address = BitVector_Resize(address,size);
616             SvREADONLY_off(handle);
617             sv_setiv(handle,(IV)address);
618             SvREADONLY_on(handle);
619             if (address == NULL) BIT_VECTOR_MEMORY_ERROR;
620         }
621         else BIT_VECTOR_SCALAR_ERROR;
622     }
623     else BIT_VECTOR_OBJECT_ERROR;
624 }
625
626
627 void
628 BitVector_DESTROY(reference)
629 BitVector_Object        reference
630 CODE:
631 {
632     BitVector_Handle  handle;
633     BitVector_Address address;
634
635     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
636     {
637         BitVector_Destroy(address);
638         SvREADONLY_off(handle);
639         sv_setiv(handle,(IV)NULL);
640         SvREADONLY_on(handle);
641     }
642     /* else BIT_VECTOR_OBJECT_ERROR; */
643 }
644
645
646 void
647 BitVector_Copy(Xref,Yref)
648 BitVector_Object        Xref
649 BitVector_Object        Yref
650 CODE:
651 {
652     BitVector_Handle  Xhdl;
653     BitVector_Address Xadr;
654     BitVector_Handle  Yhdl;
655     BitVector_Address Yadr;
656
657     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
658          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
659     {
660         BitVector_Copy(Xadr,Yadr);
661     }
662     else BIT_VECTOR_OBJECT_ERROR;
663 }
664
665
666 void
667 BitVector_Empty(reference)
668 BitVector_Object        reference
669 CODE:
670 {
671     BitVector_Handle  handle;
672     BitVector_Address address;
673
674     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
675     {
676         BitVector_Empty(address);
677     }
678     else BIT_VECTOR_OBJECT_ERROR;
679 }
680
681
682 void
683 BitVector_Fill(reference)
684 BitVector_Object        reference
685 CODE:
686 {
687     BitVector_Handle  handle;
688     BitVector_Address address;
689
690     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
691     {
692         BitVector_Fill(address);
693     }
694     else BIT_VECTOR_OBJECT_ERROR;
695 }
696
697
698 void
699 BitVector_Flip(reference)
700 BitVector_Object        reference
701 CODE:
702 {
703     BitVector_Handle  handle;
704     BitVector_Address address;
705
706     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
707     {
708         BitVector_Flip(address);
709     }
710     else BIT_VECTOR_OBJECT_ERROR;
711 }
712
713
714 void
715 BitVector_Primes(reference)
716 BitVector_Object        reference
717 CODE:
718 {
719     BitVector_Handle  handle;
720     BitVector_Address address;
721
722     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
723     {
724         BitVector_Primes(address);
725     }
726     else BIT_VECTOR_OBJECT_ERROR;
727 }
728
729
730 void
731 BitVector_Reverse(Xref,Yref)
732 BitVector_Object        Xref
733 BitVector_Object        Yref
734 CODE:
735 {
736     BitVector_Handle  Xhdl;
737     BitVector_Address Xadr;
738     BitVector_Handle  Yhdl;
739     BitVector_Address Yadr;
740
741     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
742          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
743     {
744         if (bits_(Xadr) == bits_(Yadr))
745         {
746             BitVector_Reverse(Xadr,Yadr);
747         }
748         else BIT_VECTOR_SIZE_ERROR;
749     }
750     else BIT_VECTOR_OBJECT_ERROR;
751 }
752
753
754 void
755 BitVector_Interval_Empty(reference,min,max)
756 BitVector_Object        reference
757 BitVector_Scalar        min
758 BitVector_Scalar        max
759 ALIAS:
760   Empty_Interval = 2
761 CODE:
762 {
763     BitVector_Handle  handle;
764     BitVector_Address address;
765     N_int lower;
766     N_int upper;
767
768     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
769     {
770         if ( BIT_VECTOR_SCALAR(min,N_int,lower) &&
771              BIT_VECTOR_SCALAR(max,N_int,upper) )
772         {
773             if      (lower >= bits_(address)) BIT_VECTOR_MIN_ERROR;
774             else if (upper >= bits_(address)) BIT_VECTOR_MAX_ERROR;
775             else if (lower > upper)           BIT_VECTOR_ORDER_ERROR;
776             else                       BitVector_Interval_Empty(address,lower,upper);
777         }
778         else BIT_VECTOR_SCALAR_ERROR;
779     }
780     else BIT_VECTOR_OBJECT_ERROR;
781 }
782
783
784 void
785 BitVector_Interval_Fill(reference,min,max)
786 BitVector_Object        reference
787 BitVector_Scalar        min
788 BitVector_Scalar        max
789 ALIAS:
790   Fill_Interval = 2
791 CODE:
792 {
793     BitVector_Handle  handle;
794     BitVector_Address address;
795     N_int lower;
796     N_int upper;
797
798     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
799     {
800         if ( BIT_VECTOR_SCALAR(min,N_int,lower) &&
801              BIT_VECTOR_SCALAR(max,N_int,upper) )
802         {
803             if      (lower >= bits_(address)) BIT_VECTOR_MIN_ERROR;
804             else if (upper >= bits_(address)) BIT_VECTOR_MAX_ERROR;
805             else if (lower > upper)           BIT_VECTOR_ORDER_ERROR;
806             else                       BitVector_Interval_Fill(address,lower,upper);
807         }
808         else BIT_VECTOR_SCALAR_ERROR;
809     }
810     else BIT_VECTOR_OBJECT_ERROR;
811 }
812
813
814 void
815 BitVector_Interval_Flip(reference,min,max)
816 BitVector_Object        reference
817 BitVector_Scalar        min
818 BitVector_Scalar        max
819 ALIAS:
820   Flip_Interval = 2
821 CODE:
822 {
823     BitVector_Handle  handle;
824     BitVector_Address address;
825     N_int lower;
826     N_int upper;
827
828     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
829     {
830         if ( BIT_VECTOR_SCALAR(min,N_int,lower) &&
831              BIT_VECTOR_SCALAR(max,N_int,upper) )
832         {
833             if      (lower >= bits_(address)) BIT_VECTOR_MIN_ERROR;
834             else if (upper >= bits_(address)) BIT_VECTOR_MAX_ERROR;
835             else if (lower > upper)           BIT_VECTOR_ORDER_ERROR;
836             else                       BitVector_Interval_Flip(address,lower,upper);
837         }
838         else BIT_VECTOR_SCALAR_ERROR;
839     }
840     else BIT_VECTOR_OBJECT_ERROR;
841 }
842
843
844 void
845 BitVector_Interval_Reverse(reference,min,max)
846 BitVector_Object        reference
847 BitVector_Scalar        min
848 BitVector_Scalar        max
849 CODE:
850 {
851     BitVector_Handle  handle;
852     BitVector_Address address;
853     N_int lower;
854     N_int upper;
855
856     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
857     {
858         if ( BIT_VECTOR_SCALAR(min,N_int,lower) &&
859              BIT_VECTOR_SCALAR(max,N_int,upper) )
860         {
861             if      (lower >= bits_(address)) BIT_VECTOR_MIN_ERROR;
862             else if (upper >= bits_(address)) BIT_VECTOR_MAX_ERROR;
863             else if (lower > upper)           BIT_VECTOR_ORDER_ERROR;
864             else                       BitVector_Interval_Reverse(address,lower,upper);
865         }
866         else BIT_VECTOR_SCALAR_ERROR;
867     }
868     else BIT_VECTOR_OBJECT_ERROR;
869 }
870
871
872 void
873 BitVector_Interval_Scan_inc(reference,start)
874 BitVector_Object        reference
875 BitVector_Scalar        start
876 PPCODE:
877 {
878     BitVector_Handle  handle;
879     BitVector_Address address;
880     N_int first;
881     N_int min;
882     N_int max;
883
884     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
885     {
886         if ( BIT_VECTOR_SCALAR(start,N_int,first) )
887         {
888             if (first < bits_(address))
889             {
890                 if ( BitVector_interval_scan_inc(address,first,&min,&max) )
891                 {
892                     EXTEND(sp,2);
893                     PUSHs(sv_2mortal(newSViv((IV)min)));
894                     PUSHs(sv_2mortal(newSViv((IV)max)));
895                 }
896                 /* else return empty list */
897             }
898             else BIT_VECTOR_START_ERROR;
899         }
900         else BIT_VECTOR_SCALAR_ERROR;
901     }
902     else BIT_VECTOR_OBJECT_ERROR;
903 }
904
905
906 void
907 BitVector_Interval_Scan_dec(reference,start)
908 BitVector_Object        reference
909 BitVector_Scalar        start
910 PPCODE:
911 {
912     BitVector_Handle  handle;
913     BitVector_Address address;
914     N_int first;
915     N_int min;
916     N_int max;
917
918     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
919     {
920         if ( BIT_VECTOR_SCALAR(start,N_int,first) )
921         {
922             if (first < bits_(address))
923             {
924                 if ( BitVector_interval_scan_dec(address,first,&min,&max) )
925                 {
926                     EXTEND(sp,2);
927                     PUSHs(sv_2mortal(newSViv((IV)min)));
928                     PUSHs(sv_2mortal(newSViv((IV)max)));
929                 }
930                 /* else return empty list */
931             }
932             else BIT_VECTOR_START_ERROR;
933         }
934         else BIT_VECTOR_SCALAR_ERROR;
935     }
936     else BIT_VECTOR_OBJECT_ERROR;
937 }
938
939
940 void
941 BitVector_Interval_Copy(Xref,Yref,Xoffset,Yoffset,length)
942 BitVector_Object        Xref
943 BitVector_Object        Yref
944 BitVector_Scalar        Xoffset
945 BitVector_Scalar        Yoffset
946 BitVector_Scalar        length
947 CODE:
948 {
949     BitVector_Handle  Xhdl;
950     BitVector_Address Xadr;
951     BitVector_Handle  Yhdl;
952     BitVector_Address Yadr;
953     N_int Xoff;
954     N_int Yoff;
955     N_int len;
956
957     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
958          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
959     {
960         if ( BIT_VECTOR_SCALAR(Xoffset,N_int,Xoff) &&
961              BIT_VECTOR_SCALAR(Yoffset,N_int,Yoff) &&
962              BIT_VECTOR_SCALAR(length, N_int,len) )
963         {
964             if ((Xoff < bits_(Xadr)) and (Yoff < bits_(Yadr)))
965             {
966                 if (len > 0) BitVector_Interval_Copy(Xadr,Yadr,Xoff,Yoff,len);
967             }
968             else BIT_VECTOR_OFFSET_ERROR;
969         }
970         else BIT_VECTOR_SCALAR_ERROR;
971     }
972     else BIT_VECTOR_OBJECT_ERROR;
973 }
974
975
976 void
977 BitVector_Interval_Substitute(Xref,Yref,Xoffset,Xlength,Yoffset,Ylength)
978 BitVector_Object        Xref
979 BitVector_Object        Yref
980 BitVector_Scalar        Xoffset
981 BitVector_Scalar        Xlength
982 BitVector_Scalar        Yoffset
983 BitVector_Scalar        Ylength
984 CODE:
985 {
986     BitVector_Handle  Xhdl;
987     BitVector_Address Xadr;
988     BitVector_Handle  Yhdl;
989     BitVector_Address Yadr;
990     N_int Xoff;
991     N_int Xlen;
992     N_int Yoff;
993     N_int Ylen;
994
995     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
996          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
997     {
998         if ( BIT_VECTOR_SCALAR(Xoffset,N_int,Xoff) &&
999              BIT_VECTOR_SCALAR(Xlength,N_int,Xlen) &&
1000              BIT_VECTOR_SCALAR(Yoffset,N_int,Yoff) &&
1001              BIT_VECTOR_SCALAR(Ylength,N_int,Ylen) )
1002         {
1003             if ((Xoff <= bits_(Xadr)) and (Yoff <= bits_(Yadr)))
1004             {
1005                 Xadr = BitVector_Interval_Substitute(Xadr,Yadr,Xoff,Xlen,Yoff,Ylen);
1006                 SvREADONLY_off(Xhdl);
1007                 sv_setiv(Xhdl,(IV)Xadr);
1008                 SvREADONLY_on(Xhdl);
1009                 if (Xadr == NULL) BIT_VECTOR_MEMORY_ERROR;
1010             }
1011             else BIT_VECTOR_OFFSET_ERROR;
1012         }
1013         else BIT_VECTOR_SCALAR_ERROR;
1014     }
1015     else BIT_VECTOR_OBJECT_ERROR;
1016 }
1017
1018
1019 boolean
1020 BitVector_is_empty(reference)
1021 BitVector_Object        reference
1022 CODE:
1023 {
1024     BitVector_Handle  handle;
1025     BitVector_Address address;
1026
1027     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1028     {
1029         RETVAL = BitVector_is_empty(address);
1030     }
1031     else BIT_VECTOR_OBJECT_ERROR;
1032 }
1033 OUTPUT:
1034 RETVAL
1035
1036
1037 boolean
1038 BitVector_is_full(reference)
1039 BitVector_Object        reference
1040 CODE:
1041 {
1042     BitVector_Handle  handle;
1043     BitVector_Address address;
1044
1045     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1046     {
1047         RETVAL = BitVector_is_full(address);
1048     }
1049     else BIT_VECTOR_OBJECT_ERROR;
1050 }
1051 OUTPUT:
1052 RETVAL
1053
1054
1055 boolean
1056 BitVector_equal(Xref,Yref)
1057 BitVector_Object        Xref
1058 BitVector_Object        Yref
1059 CODE:
1060 {
1061     BitVector_Handle  Xhdl;
1062     BitVector_Address Xadr;
1063     BitVector_Handle  Yhdl;
1064     BitVector_Address Yadr;
1065
1066     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1067          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1068     {
1069         if (bits_(Xadr) == bits_(Yadr))
1070         {
1071             RETVAL = BitVector_equal(Xadr,Yadr);
1072         }
1073         else BIT_VECTOR_SIZE_ERROR;
1074     }
1075     else BIT_VECTOR_OBJECT_ERROR;
1076 }
1077 OUTPUT:
1078 RETVAL
1079
1080
1081 Z_int
1082 BitVector_Lexicompare(Xref,Yref)
1083 BitVector_Object        Xref
1084 BitVector_Object        Yref
1085 CODE:
1086 {
1087     BitVector_Handle  Xhdl;
1088     BitVector_Address Xadr;
1089     BitVector_Handle  Yhdl;
1090     BitVector_Address Yadr;
1091
1092     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1093          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1094     {
1095         if (bits_(Xadr) == bits_(Yadr))
1096         {
1097             RETVAL = BitVector_Lexicompare(Xadr,Yadr);
1098         }
1099         else BIT_VECTOR_SIZE_ERROR;
1100     }
1101     else BIT_VECTOR_OBJECT_ERROR;
1102 }
1103 OUTPUT:
1104 RETVAL
1105
1106
1107 Z_int
1108 BitVector_Compare(Xref,Yref)
1109 BitVector_Object        Xref
1110 BitVector_Object        Yref
1111 CODE:
1112 {
1113     BitVector_Handle  Xhdl;
1114     BitVector_Address Xadr;
1115     BitVector_Handle  Yhdl;
1116     BitVector_Address Yadr;
1117
1118     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1119          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1120     {
1121         if (bits_(Xadr) == bits_(Yadr))
1122         {
1123             RETVAL = BitVector_Compare(Xadr,Yadr);
1124         }
1125         else BIT_VECTOR_SIZE_ERROR;
1126     }
1127     else BIT_VECTOR_OBJECT_ERROR;
1128 }
1129 OUTPUT:
1130 RETVAL
1131
1132
1133 void
1134 BitVector_to_Hex(reference)
1135 BitVector_Object        reference
1136 ALIAS:
1137   to_String = 2
1138 PPCODE:
1139 {
1140     BitVector_Handle  handle;
1141     BitVector_Address address;
1142     charptr string;
1143
1144     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1145     {
1146         string = BitVector_to_Hex(address);
1147         if (string != NULL)
1148         {
1149             EXTEND(sp,1);
1150             PUSHs(sv_2mortal(newSVpv((char *)string,0)));
1151             BitVector_Dispose(string);
1152         }
1153         else BIT_VECTOR_MEMORY_ERROR;
1154     }
1155     else BIT_VECTOR_OBJECT_ERROR;
1156 }
1157
1158
1159 void
1160 BitVector_from_Hex(reference,string)
1161 BitVector_Object        reference
1162 BitVector_Scalar        string
1163 ALIAS:
1164   from_string = 2
1165 CODE:
1166 {
1167     BitVector_Handle  handle;
1168     BitVector_Address address;
1169     charptr pointer;
1170     ErrCode code;
1171
1172     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1173     {
1174         if ( BIT_VECTOR_STRING(string,pointer) )
1175         {
1176             if ((code = BitVector_from_Hex(address,pointer)))
1177                 BIT_VECTOR_EXCEPTION(code);
1178         }
1179         else BIT_VECTOR_STRING_ERROR;
1180     }
1181     else BIT_VECTOR_OBJECT_ERROR;
1182 }
1183
1184
1185 void
1186 BitVector_to_Bin(reference)
1187 BitVector_Object        reference
1188 PPCODE:
1189 {
1190     BitVector_Handle  handle;
1191     BitVector_Address address;
1192     charptr string;
1193
1194     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1195     {
1196         string = BitVector_to_Bin(address);
1197         if (string != NULL)
1198         {
1199             EXTEND(sp,1);
1200             PUSHs(sv_2mortal(newSVpv((char *)string,0)));
1201             BitVector_Dispose(string);
1202         }
1203         else BIT_VECTOR_MEMORY_ERROR;
1204     }
1205     else BIT_VECTOR_OBJECT_ERROR;
1206 }
1207
1208
1209 void
1210 BitVector_from_Bin(reference,string)
1211 BitVector_Object        reference
1212 BitVector_Scalar        string
1213 CODE:
1214 {
1215     BitVector_Handle  handle;
1216     BitVector_Address address;
1217     charptr pointer;
1218     ErrCode code;
1219
1220     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1221     {
1222         if ( BIT_VECTOR_STRING(string,pointer) )
1223         {
1224             if ((code = BitVector_from_Bin(address,pointer)))
1225                 BIT_VECTOR_EXCEPTION(code);
1226         }
1227         else BIT_VECTOR_STRING_ERROR;
1228     }
1229     else BIT_VECTOR_OBJECT_ERROR;
1230 }
1231
1232
1233 void
1234 BitVector_to_Dec(reference)
1235 BitVector_Object        reference
1236 PPCODE:
1237 {
1238     BitVector_Handle  handle;
1239     BitVector_Address address;
1240     charptr string;
1241
1242     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1243     {
1244         string = BitVector_to_Dec(address);
1245         if (string != NULL)
1246         {
1247             EXTEND(sp,1);
1248             PUSHs(sv_2mortal(newSVpv((char *)string,0)));
1249             BitVector_Dispose(string);
1250         }
1251         else BIT_VECTOR_MEMORY_ERROR;
1252     }
1253     else BIT_VECTOR_OBJECT_ERROR;
1254 }
1255
1256
1257 void
1258 BitVector_from_Dec(reference,string)
1259 BitVector_Object        reference
1260 BitVector_Scalar        string
1261 CODE:
1262 {
1263     BitVector_Handle  handle;
1264     BitVector_Address address;
1265     charptr pointer;
1266     ErrCode code;
1267
1268     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1269     {
1270         if ( BIT_VECTOR_STRING(string,pointer) )
1271         {
1272             if ((code = BitVector_from_Dec(address,pointer)))
1273                 BIT_VECTOR_EXCEPTION(code);
1274         }
1275         else BIT_VECTOR_STRING_ERROR;
1276     }
1277     else BIT_VECTOR_OBJECT_ERROR;
1278 }
1279
1280
1281 void
1282 BitVector_to_Enum(reference)
1283 BitVector_Object        reference
1284 ALIAS:
1285   to_ASCII = 2
1286 PPCODE:
1287 {
1288     BitVector_Handle  handle;
1289     BitVector_Address address;
1290     charptr string;
1291
1292     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1293     {
1294         string = BitVector_to_Enum(address);
1295         if (string != NULL)
1296         {
1297             EXTEND(sp,1);
1298             PUSHs(sv_2mortal(newSVpv((char *)string,0)));
1299             BitVector_Dispose(string);
1300         }
1301         else BIT_VECTOR_MEMORY_ERROR;
1302     }
1303     else BIT_VECTOR_OBJECT_ERROR;
1304 }
1305
1306
1307 void
1308 BitVector_from_Enum(reference,string)
1309 BitVector_Object        reference
1310 BitVector_Scalar        string
1311 ALIAS:
1312   from_ASCII = 2
1313 CODE:
1314 {
1315     BitVector_Handle  handle;
1316     BitVector_Address address;
1317     charptr pointer;
1318     ErrCode code;
1319
1320     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1321     {
1322         if ( BIT_VECTOR_STRING(string,pointer) )
1323         {
1324             if ((code = BitVector_from_Enum(address,pointer)))
1325                 BIT_VECTOR_EXCEPTION(code);
1326         }
1327         else BIT_VECTOR_STRING_ERROR;
1328     }
1329     else BIT_VECTOR_OBJECT_ERROR;
1330 }
1331
1332
1333 void
1334 BitVector_Bit_Off(reference,index)
1335 BitVector_Object        reference
1336 BitVector_Scalar        index
1337 CODE:
1338 {
1339     BitVector_Handle  handle;
1340     BitVector_Address address;
1341     N_int idx;
1342
1343     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1344     {
1345         if ( BIT_VECTOR_SCALAR(index,N_int,idx) )
1346         {
1347             if (idx < bits_(address))
1348             {
1349                 BitVector_Bit_Off(address,idx);
1350             }
1351             else BIT_VECTOR_INDEX_ERROR;
1352         }
1353         else BIT_VECTOR_SCALAR_ERROR;
1354     }
1355     else BIT_VECTOR_OBJECT_ERROR;
1356 }
1357
1358
1359 void
1360 BitVector_Bit_On(reference,index)
1361 BitVector_Object        reference
1362 BitVector_Scalar        index
1363 CODE:
1364 {
1365     BitVector_Handle  handle;
1366     BitVector_Address address;
1367     N_int idx;
1368
1369     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1370     {
1371         if ( BIT_VECTOR_SCALAR(index,N_int,idx) )
1372         {
1373             if (idx < bits_(address))
1374             {
1375                 BitVector_Bit_On(address,idx);
1376             }
1377             else BIT_VECTOR_INDEX_ERROR;
1378         }
1379         else BIT_VECTOR_SCALAR_ERROR;
1380     }
1381     else BIT_VECTOR_OBJECT_ERROR;
1382 }
1383
1384
1385 boolean
1386 BitVector_bit_flip(reference,index)
1387 BitVector_Object        reference
1388 BitVector_Scalar        index
1389 ALIAS:
1390   flip = 2
1391 CODE:
1392 {
1393     BitVector_Handle  handle;
1394     BitVector_Address address;
1395     N_int idx;
1396
1397     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1398     {
1399         if ( BIT_VECTOR_SCALAR(index,N_int,idx) )
1400         {
1401             if (idx < bits_(address))
1402             {
1403                 RETVAL = BitVector_bit_flip(address,idx);
1404             }
1405             else BIT_VECTOR_INDEX_ERROR;
1406         }
1407         else BIT_VECTOR_SCALAR_ERROR;
1408     }
1409     else BIT_VECTOR_OBJECT_ERROR;
1410 }
1411 OUTPUT:
1412 RETVAL
1413
1414
1415 boolean
1416 BitVector_bit_test(reference,index)
1417 BitVector_Object        reference
1418 BitVector_Scalar        index
1419 ALIAS:
1420   contains = 1
1421   in = 2
1422 CODE:
1423 {
1424     BitVector_Handle  handle;
1425     BitVector_Address address;
1426     N_int idx;
1427
1428     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1429     {
1430         if ( BIT_VECTOR_SCALAR(index,N_int,idx) )
1431         {
1432             if (idx < bits_(address))
1433             {
1434                 RETVAL = BitVector_bit_test(address,idx);
1435             }
1436             else BIT_VECTOR_INDEX_ERROR;
1437         }
1438         else BIT_VECTOR_SCALAR_ERROR;
1439     }
1440     else BIT_VECTOR_OBJECT_ERROR;
1441 }
1442 OUTPUT:
1443 RETVAL
1444
1445
1446 void
1447 BitVector_Bit_Copy(reference,index,bit)
1448 BitVector_Object        reference
1449 BitVector_Scalar        index
1450 BitVector_Scalar        bit
1451 CODE:
1452 {
1453     BitVector_Handle  handle;
1454     BitVector_Address address;
1455     N_int idx;
1456     boolean b;
1457
1458     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1459     {
1460         if ( BIT_VECTOR_SCALAR(index,N_int,idx) &&
1461              BIT_VECTOR_SCALAR(bit,boolean,b) )
1462         {
1463             if (idx < bits_(address))
1464             {
1465                 BitVector_Bit_Copy(address,idx,b);
1466             }
1467             else BIT_VECTOR_INDEX_ERROR;
1468         }
1469         else BIT_VECTOR_SCALAR_ERROR;
1470     }
1471     else BIT_VECTOR_OBJECT_ERROR;
1472 }
1473
1474
1475 void
1476 BitVector_LSB(reference,bit)
1477 BitVector_Object        reference
1478 BitVector_Scalar        bit
1479 CODE:
1480 {
1481     BitVector_Handle  handle;
1482     BitVector_Address address;
1483     boolean b;
1484
1485     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1486     {
1487         if ( BIT_VECTOR_SCALAR(bit,boolean,b) )
1488         {
1489             BitVector_LSB(address,b);
1490         }
1491         else BIT_VECTOR_SCALAR_ERROR;
1492     }
1493     else BIT_VECTOR_OBJECT_ERROR;
1494 }
1495
1496
1497 void
1498 BitVector_MSB(reference,bit)
1499 BitVector_Object        reference
1500 BitVector_Scalar        bit
1501 CODE:
1502 {
1503     BitVector_Handle  handle;
1504     BitVector_Address address;
1505     boolean b;
1506
1507     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1508     {
1509         if ( BIT_VECTOR_SCALAR(bit,boolean,b) )
1510         {
1511             BitVector_MSB(address,b);
1512         }
1513         else BIT_VECTOR_SCALAR_ERROR;
1514     }
1515     else BIT_VECTOR_OBJECT_ERROR;
1516 }
1517
1518
1519 boolean
1520 BitVector_lsb(reference)
1521 BitVector_Object        reference
1522 CODE:
1523 {
1524     BitVector_Handle  handle;
1525     BitVector_Address address;
1526
1527     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1528     {
1529         RETVAL = BitVector_lsb_(address);
1530     }
1531     else BIT_VECTOR_OBJECT_ERROR;
1532 }
1533 OUTPUT:
1534 RETVAL
1535
1536
1537 boolean
1538 BitVector_msb(reference)
1539 BitVector_Object        reference
1540 CODE:
1541 {
1542     BitVector_Handle  handle;
1543     BitVector_Address address;
1544
1545     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1546     {
1547         RETVAL = BitVector_msb_(address);
1548     }
1549     else BIT_VECTOR_OBJECT_ERROR;
1550 }
1551 OUTPUT:
1552 RETVAL
1553
1554
1555 boolean
1556 BitVector_rotate_left(reference)
1557 BitVector_Object        reference
1558 CODE:
1559 {
1560     BitVector_Handle  handle;
1561     BitVector_Address address;
1562
1563     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1564     {
1565         RETVAL = BitVector_rotate_left(address);
1566     }
1567     else BIT_VECTOR_OBJECT_ERROR;
1568 }
1569 OUTPUT:
1570 RETVAL
1571
1572
1573 boolean
1574 BitVector_rotate_right(reference)
1575 BitVector_Object        reference
1576 CODE:
1577 {
1578     BitVector_Handle  handle;
1579     BitVector_Address address;
1580
1581     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1582     {
1583         RETVAL = BitVector_rotate_right(address);
1584     }
1585     else BIT_VECTOR_OBJECT_ERROR;
1586 }
1587 OUTPUT:
1588 RETVAL
1589
1590
1591 boolean
1592 BitVector_shift_left(reference,carry)
1593 BitVector_Object        reference
1594 BitVector_Scalar        carry
1595 CODE:
1596 {
1597     BitVector_Handle  handle;
1598     BitVector_Address address;
1599     boolean c;
1600
1601     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1602     {
1603         if ( BIT_VECTOR_SCALAR(carry,boolean,c) )
1604         {
1605             RETVAL = BitVector_shift_left(address,c);
1606         }
1607         else BIT_VECTOR_SCALAR_ERROR;
1608     }
1609     else BIT_VECTOR_OBJECT_ERROR;
1610 }
1611 OUTPUT:
1612 RETVAL
1613
1614
1615 boolean
1616 BitVector_shift_right(reference,carry)
1617 BitVector_Object        reference
1618 BitVector_Scalar        carry
1619 CODE:
1620 {
1621     BitVector_Handle  handle;
1622     BitVector_Address address;
1623     boolean c;
1624
1625     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1626     {
1627         if ( BIT_VECTOR_SCALAR(carry,boolean,c) )
1628         {
1629             RETVAL = BitVector_shift_right(address,c);
1630         }
1631         else BIT_VECTOR_SCALAR_ERROR;
1632     }
1633     else BIT_VECTOR_OBJECT_ERROR;
1634 }
1635 OUTPUT:
1636 RETVAL
1637
1638
1639 void
1640 BitVector_Move_Left(reference,bits)
1641 BitVector_Object        reference
1642 BitVector_Scalar        bits
1643 CODE:
1644 {
1645     BitVector_Handle  handle;
1646     BitVector_Address address;
1647     N_int cnt;
1648
1649     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1650     {
1651         if ( BIT_VECTOR_SCALAR(bits,N_int,cnt) )
1652         {
1653             BitVector_Move_Left(address,cnt);
1654         }
1655         else BIT_VECTOR_SCALAR_ERROR;
1656     }
1657     else BIT_VECTOR_OBJECT_ERROR;
1658 }
1659
1660
1661 void
1662 BitVector_Move_Right(reference,bits)
1663 BitVector_Object        reference
1664 BitVector_Scalar        bits
1665 CODE:
1666 {
1667     BitVector_Handle  handle;
1668     BitVector_Address address;
1669     N_int cnt;
1670
1671     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1672     {
1673         if ( BIT_VECTOR_SCALAR(bits,N_int,cnt) )
1674         {
1675             BitVector_Move_Right(address,cnt);
1676         }
1677         else BIT_VECTOR_SCALAR_ERROR;
1678     }
1679     else BIT_VECTOR_OBJECT_ERROR;
1680 }
1681
1682
1683 void
1684 BitVector_Insert(reference,offset,count)
1685 BitVector_Object        reference
1686 BitVector_Scalar        offset
1687 BitVector_Scalar        count
1688 CODE:
1689 {
1690     BitVector_Handle  handle;
1691     BitVector_Address address;
1692     N_int off;
1693     N_int cnt;
1694
1695     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1696     {
1697         if ( BIT_VECTOR_SCALAR(offset,N_int,off) &&
1698              BIT_VECTOR_SCALAR(count,N_int,cnt) )
1699         {
1700             if (off < bits_(address))
1701             {
1702                 BitVector_Insert(address,off,cnt,true);
1703             }
1704             else BIT_VECTOR_OFFSET_ERROR;
1705         }
1706         else BIT_VECTOR_SCALAR_ERROR;
1707     }
1708     else BIT_VECTOR_OBJECT_ERROR;
1709 }
1710
1711
1712 void
1713 BitVector_Delete(reference,offset,count)
1714 BitVector_Object        reference
1715 BitVector_Scalar        offset
1716 BitVector_Scalar        count
1717 CODE:
1718 {
1719     BitVector_Handle  handle;
1720     BitVector_Address address;
1721     N_int off;
1722     N_int cnt;
1723
1724     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1725     {
1726         if ( BIT_VECTOR_SCALAR(offset,N_int,off) &&
1727              BIT_VECTOR_SCALAR(count,N_int,cnt) )
1728         {
1729             if (off < bits_(address))
1730             {
1731                 BitVector_Delete(address,off,cnt,true);
1732             }
1733             else BIT_VECTOR_OFFSET_ERROR;
1734         }
1735         else BIT_VECTOR_SCALAR_ERROR;
1736     }
1737     else BIT_VECTOR_OBJECT_ERROR;
1738 }
1739
1740
1741 boolean
1742 BitVector_increment(reference)
1743 BitVector_Object        reference
1744 CODE:
1745 {
1746     BitVector_Handle  handle;
1747     BitVector_Address address;
1748
1749     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1750     {
1751         RETVAL = BitVector_increment(address);
1752     }
1753     else BIT_VECTOR_OBJECT_ERROR;
1754 }
1755 OUTPUT:
1756 RETVAL
1757
1758
1759 boolean
1760 BitVector_decrement(reference)
1761 BitVector_Object        reference
1762 CODE:
1763 {
1764     BitVector_Handle  handle;
1765     BitVector_Address address;
1766
1767     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1768     {
1769         RETVAL = BitVector_decrement(address);
1770     }
1771     else BIT_VECTOR_OBJECT_ERROR;
1772 }
1773 OUTPUT:
1774 RETVAL
1775
1776
1777 void
1778 BitVector_add(Xref,Yref,Zref,carry)
1779 BitVector_Object        Xref
1780 BitVector_Object        Yref
1781 BitVector_Object        Zref
1782 BitVector_Scalar        carry
1783 PPCODE:
1784 {
1785     BitVector_Handle  Xhdl;
1786     BitVector_Address Xadr;
1787     BitVector_Handle  Yhdl;
1788     BitVector_Address Yadr;
1789     BitVector_Handle  Zhdl;
1790     BitVector_Address Zadr;
1791     boolean c;
1792     boolean v;
1793
1794     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1795          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
1796          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
1797     {
1798         if ( BIT_VECTOR_SCALAR(carry,boolean,c) )
1799         {
1800             if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
1801             {
1802                 v = BitVector_compute(Xadr,Yadr,Zadr,false,&c);
1803                 if (GIMME_V == G_ARRAY)
1804                 {
1805                     EXTEND(sp,2);
1806                     PUSHs(sv_2mortal(newSViv((IV)c)));
1807                     PUSHs(sv_2mortal(newSViv((IV)v)));
1808                 }
1809                 else
1810                 {
1811                     EXTEND(sp,1);
1812                     PUSHs(sv_2mortal(newSViv((IV)c)));
1813                 }
1814             }
1815             else BIT_VECTOR_SIZE_ERROR;
1816         }
1817         else BIT_VECTOR_SCALAR_ERROR;
1818     }
1819     else BIT_VECTOR_OBJECT_ERROR;
1820 }
1821
1822
1823 void
1824 BitVector_subtract(Xref,Yref,Zref,carry)
1825 BitVector_Object        Xref
1826 BitVector_Object        Yref
1827 BitVector_Object        Zref
1828 BitVector_Scalar        carry
1829 ALIAS:
1830   sub = 2
1831 PPCODE:
1832 {
1833     BitVector_Handle  Xhdl;
1834     BitVector_Address Xadr;
1835     BitVector_Handle  Yhdl;
1836     BitVector_Address Yadr;
1837     BitVector_Handle  Zhdl;
1838     BitVector_Address Zadr;
1839     boolean c;
1840     boolean v;
1841
1842     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1843          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
1844          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
1845     {
1846         if ( BIT_VECTOR_SCALAR(carry,boolean,c) )
1847         {
1848             if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
1849             {
1850                 v = BitVector_compute(Xadr,Yadr,Zadr,true,&c);
1851                 if (GIMME_V == G_ARRAY)
1852                 {
1853                     EXTEND(sp,2);
1854                     PUSHs(sv_2mortal(newSViv((IV)c)));
1855                     PUSHs(sv_2mortal(newSViv((IV)v)));
1856                 }
1857                 else
1858                 {
1859                     EXTEND(sp,1);
1860                     PUSHs(sv_2mortal(newSViv((IV)c)));
1861                 }
1862             }
1863             else BIT_VECTOR_SIZE_ERROR;
1864         }
1865         else BIT_VECTOR_SCALAR_ERROR;
1866     }
1867     else BIT_VECTOR_OBJECT_ERROR;
1868 }
1869
1870
1871 boolean
1872 BitVector_inc(Xref,Yref)
1873 BitVector_Object        Xref
1874 BitVector_Object        Yref
1875 CODE:
1876 {
1877     BitVector_Handle  Xhdl;
1878     BitVector_Address Xadr;
1879     BitVector_Handle  Yhdl;
1880     BitVector_Address Yadr;
1881     boolean c = true;
1882
1883     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1884          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1885     {
1886         if (bits_(Xadr) == bits_(Yadr))
1887         {
1888             RETVAL = BitVector_compute(Xadr,Yadr,NULL,false,&c);
1889         }
1890         else BIT_VECTOR_SIZE_ERROR;
1891     }
1892     else BIT_VECTOR_OBJECT_ERROR;
1893 }
1894 OUTPUT:
1895 RETVAL
1896
1897
1898 boolean
1899 BitVector_dec(Xref,Yref)
1900 BitVector_Object        Xref
1901 BitVector_Object        Yref
1902 CODE:
1903 {
1904     BitVector_Handle  Xhdl;
1905     BitVector_Address Xadr;
1906     BitVector_Handle  Yhdl;
1907     BitVector_Address Yadr;
1908     boolean c = true;
1909
1910     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1911          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1912     {
1913         if (bits_(Xadr) == bits_(Yadr))
1914         {
1915             RETVAL = BitVector_compute(Xadr,Yadr,NULL,true,&c);
1916         }
1917         else BIT_VECTOR_SIZE_ERROR;
1918     }
1919     else BIT_VECTOR_OBJECT_ERROR;
1920 }
1921 OUTPUT:
1922 RETVAL
1923
1924
1925 void
1926 BitVector_Negate(Xref,Yref)
1927 BitVector_Object        Xref
1928 BitVector_Object        Yref
1929 ALIAS:
1930   Neg = 1
1931 CODE:
1932 {
1933     BitVector_Handle  Xhdl;
1934     BitVector_Address Xadr;
1935     BitVector_Handle  Yhdl;
1936     BitVector_Address Yadr;
1937
1938     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1939          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1940     {
1941         if (bits_(Xadr) == bits_(Yadr))
1942         {
1943             BitVector_Negate(Xadr,Yadr);
1944         }
1945         else BIT_VECTOR_SIZE_ERROR;
1946     }
1947     else BIT_VECTOR_OBJECT_ERROR;
1948 }
1949
1950
1951 void
1952 BitVector_Absolute(Xref,Yref)
1953 BitVector_Object        Xref
1954 BitVector_Object        Yref
1955 ALIAS:
1956   Abs = 1
1957 CODE:
1958 {
1959     BitVector_Handle  Xhdl;
1960     BitVector_Address Xadr;
1961     BitVector_Handle  Yhdl;
1962     BitVector_Address Yadr;
1963
1964     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
1965          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
1966     {
1967         if (bits_(Xadr) == bits_(Yadr))
1968         {
1969             BitVector_Absolute(Xadr,Yadr);
1970         }
1971         else BIT_VECTOR_SIZE_ERROR;
1972     }
1973     else BIT_VECTOR_OBJECT_ERROR;
1974 }
1975
1976
1977 Z_int
1978 BitVector_Sign(reference)
1979 BitVector_Object        reference
1980 CODE:
1981 {
1982     BitVector_Handle  handle;
1983     BitVector_Address address;
1984
1985     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
1986     {
1987         RETVAL = BitVector_Sign(address);
1988     }
1989     else BIT_VECTOR_OBJECT_ERROR;
1990 }
1991 OUTPUT:
1992 RETVAL
1993
1994
1995 void
1996 BitVector_Multiply(Xref,Yref,Zref)
1997 BitVector_Object        Xref
1998 BitVector_Object        Yref
1999 BitVector_Object        Zref
2000 CODE:
2001 {
2002     BitVector_Handle  Xhdl;
2003     BitVector_Address Xadr;
2004     BitVector_Handle  Yhdl;
2005     BitVector_Address Yadr;
2006     BitVector_Handle  Zhdl;
2007     BitVector_Address Zadr;
2008     ErrCode           code;
2009
2010     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2011          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2012          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2013     {
2014         if ((bits_(Xadr) >= bits_(Yadr)) and (bits_(Yadr) == bits_(Zadr)))
2015         {
2016             if ((code = BitVector_Multiply(Xadr,Yadr,Zadr)))
2017                 BIT_VECTOR_EXCEPTION(code);
2018         }
2019         else BIT_VECTOR_SIZE_ERROR;
2020     }
2021     else BIT_VECTOR_OBJECT_ERROR;
2022 }
2023
2024
2025 void
2026 BitVector_Divide(Qref,Xref,Yref,Rref)
2027 BitVector_Object        Qref
2028 BitVector_Object        Xref
2029 BitVector_Object        Yref
2030 BitVector_Object        Rref
2031 CODE:
2032 {
2033     BitVector_Handle  Qhdl;
2034     BitVector_Address Qadr;
2035     BitVector_Handle  Xhdl;
2036     BitVector_Address Xadr;
2037     BitVector_Handle  Yhdl;
2038     BitVector_Address Yadr;
2039     BitVector_Handle  Rhdl;
2040     BitVector_Address Radr;
2041     ErrCode           code;
2042
2043     if ( BIT_VECTOR_OBJECT(Qref,Qhdl,Qadr) &&
2044          BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2045          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2046          BIT_VECTOR_OBJECT(Rref,Rhdl,Radr) )
2047     {
2048         if ((code = BitVector_Divide(Qadr,Xadr,Yadr,Radr)))
2049             BIT_VECTOR_EXCEPTION(code);
2050     }
2051     else BIT_VECTOR_OBJECT_ERROR;
2052 }
2053
2054
2055 void
2056 BitVector_GCD(...)
2057 CODE:
2058 {
2059     BitVector_Object  Uref;
2060     BitVector_Handle  Uhdl;
2061     BitVector_Address Uadr;
2062     BitVector_Object  Vref;
2063     BitVector_Handle  Vhdl;
2064     BitVector_Address Vadr;
2065     BitVector_Object  Wref;
2066     BitVector_Handle  Whdl;
2067     BitVector_Address Wadr;
2068     BitVector_Object  Xref;
2069     BitVector_Handle  Xhdl;
2070     BitVector_Address Xadr;
2071     BitVector_Object  Yref;
2072     BitVector_Handle  Yhdl;
2073     BitVector_Address Yadr;
2074     ErrCode           code;
2075
2076     if      (items == 3)
2077     {
2078         Uref = ST(0);
2079         Xref = ST(1);
2080         Yref = ST(2);
2081         if ( BIT_VECTOR_OBJECT(Uref,Uhdl,Uadr) &&
2082              BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2083              BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
2084         {
2085             if ((code = BitVector_GCD(Uadr,Xadr,Yadr)))
2086                 BIT_VECTOR_EXCEPTION(code);
2087         }
2088         else BIT_VECTOR_OBJECT_ERROR;
2089     }
2090     else if (items == 5)
2091     {
2092         Uref = ST(0);
2093         Vref = ST(1);
2094         Wref = ST(2);
2095         Xref = ST(3);
2096         Yref = ST(4);
2097         if ( BIT_VECTOR_OBJECT(Uref,Uhdl,Uadr) &&
2098              BIT_VECTOR_OBJECT(Vref,Vhdl,Vadr) &&
2099              BIT_VECTOR_OBJECT(Wref,Whdl,Wadr) &&
2100              BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2101              BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
2102         {
2103             if ((code = BitVector_GCD2(Uadr,Vadr,Wadr,Xadr,Yadr)))
2104                 BIT_VECTOR_EXCEPTION(code);
2105         }
2106         else BIT_VECTOR_OBJECT_ERROR;
2107     }
2108     else croak("Usage: %s(Uref[,Vref,Wref],Xref,Yref)", GvNAME(CvGV(cv)));
2109 }
2110
2111
2112 void
2113 BitVector_Power(Xref,Yref,Zref)
2114 BitVector_Object        Xref
2115 BitVector_Object        Yref
2116 BitVector_Object        Zref
2117 CODE:
2118 {
2119     BitVector_Handle  Xhdl;
2120     BitVector_Address Xadr;
2121     BitVector_Handle  Yhdl;
2122     BitVector_Address Yadr;
2123     BitVector_Handle  Zhdl;
2124     BitVector_Address Zadr;
2125     ErrCode           code;
2126
2127     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2128          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2129          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2130     {
2131         if ((code = BitVector_Power(Xadr,Yadr,Zadr)))
2132             BIT_VECTOR_EXCEPTION(code);
2133     }
2134     else BIT_VECTOR_OBJECT_ERROR;
2135 }
2136
2137
2138 void
2139 BitVector_Block_Store(reference,buffer)
2140 BitVector_Object        reference
2141 BitVector_Scalar        buffer
2142 CODE:
2143 {
2144     BitVector_Handle  handle;
2145     BitVector_Address address;
2146     charptr string;
2147     N_int length;
2148
2149     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2150     {
2151         if ( BIT_VECTOR_BUFFER(buffer,string,length) )
2152         {
2153             BitVector_Block_Store(address,string,length);
2154         }
2155         else BIT_VECTOR_STRING_ERROR;
2156     }
2157     else BIT_VECTOR_OBJECT_ERROR;
2158 }
2159
2160
2161 void
2162 BitVector_Block_Read(reference)
2163 BitVector_Object        reference
2164 PPCODE:
2165 {
2166     BitVector_Handle  handle;
2167     BitVector_Address address;
2168     charptr string;
2169     N_int length;
2170
2171     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2172     {
2173         string = BitVector_Block_Read(address,&length);
2174         if (string != NULL)
2175         {
2176             EXTEND(sp,1);
2177             PUSHs(sv_2mortal(newSVpv((char *)string,length)));
2178             BitVector_Dispose(string);
2179         }
2180         else BIT_VECTOR_MEMORY_ERROR;
2181     }
2182     else BIT_VECTOR_OBJECT_ERROR;
2183 }
2184
2185
2186 N_int
2187 BitVector_Word_Size(reference)
2188 BitVector_Object        reference
2189 CODE:
2190 {
2191     BitVector_Handle  handle;
2192     BitVector_Address address;
2193
2194     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2195     {
2196         RETVAL = size_(address);
2197     }
2198     else BIT_VECTOR_OBJECT_ERROR;
2199 }
2200 OUTPUT:
2201 RETVAL
2202
2203
2204 void
2205 BitVector_Word_Store(reference,offset,value)
2206 BitVector_Object        reference
2207 BitVector_Scalar        offset
2208 BitVector_Scalar        value
2209 CODE:
2210 {
2211     BitVector_Handle  handle;
2212     BitVector_Address address;
2213     N_int off;
2214     N_int val;
2215
2216     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2217     {
2218         if ( BIT_VECTOR_SCALAR(offset,N_int,off) &&
2219              BIT_VECTOR_SCALAR(value,N_int,val) )
2220         {
2221             if (off < size_(address))
2222             {
2223                 BitVector_Word_Store(address,off,val);
2224             }
2225             else BIT_VECTOR_OFFSET_ERROR;
2226         }
2227         else BIT_VECTOR_SCALAR_ERROR;
2228     }
2229     else BIT_VECTOR_OBJECT_ERROR;
2230 }
2231
2232
2233 N_int
2234 BitVector_Word_Read(reference,offset)
2235 BitVector_Object        reference
2236 BitVector_Scalar        offset
2237 CODE:
2238 {
2239     BitVector_Handle  handle;
2240     BitVector_Address address;
2241     N_int off;
2242
2243     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2244     {
2245         if ( BIT_VECTOR_SCALAR(offset,N_int,off) )
2246         {
2247             if (off < size_(address))
2248             {
2249                 RETVAL = BitVector_Word_Read(address,off);
2250             }
2251             else BIT_VECTOR_OFFSET_ERROR;
2252         }
2253         else BIT_VECTOR_SCALAR_ERROR;
2254     }
2255     else BIT_VECTOR_OBJECT_ERROR;
2256 }
2257 OUTPUT:
2258 RETVAL
2259
2260
2261 void
2262 BitVector_Word_List_Store(reference,...)
2263 BitVector_Object        reference
2264 CODE:
2265 {
2266     BitVector_Handle  handle;
2267     BitVector_Address address;
2268     BitVector_Scalar  scalar;
2269     N_int offset;
2270     N_int value;
2271     N_int size;
2272     I32 index;
2273
2274     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2275     {
2276         size = size_(address);
2277         for ( offset = 0, index = 1;
2278             ((offset < size) and (index < items)); offset++, index++ )
2279         {
2280             scalar = ST(index);
2281             if ( BIT_VECTOR_SCALAR(scalar,N_int,value) )
2282             {
2283                 BitVector_Word_Store(address,offset,value);
2284             }
2285             else BIT_VECTOR_SCALAR_ERROR;
2286         }
2287         for ( ; (offset < size); offset++ )
2288         {
2289             BitVector_Word_Store(address,offset,0);
2290         }
2291     }
2292     else BIT_VECTOR_OBJECT_ERROR;
2293 }
2294
2295
2296 void
2297 BitVector_Word_List_Read(reference)
2298 BitVector_Object        reference
2299 PPCODE:
2300 {
2301     BitVector_Handle  handle;
2302     BitVector_Address address;
2303     N_int offset;
2304     N_int value;
2305     N_int size;
2306
2307     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2308     {
2309         size = size_(address);
2310         EXTEND(sp,(int)size);
2311         for ( offset = 0; (offset < size); offset++ )
2312         {
2313             value = BitVector_Word_Read(address,offset);
2314             PUSHs(sv_2mortal(newSViv((IV)value)));
2315         }
2316     }
2317     else BIT_VECTOR_OBJECT_ERROR;
2318 }
2319
2320
2321 void
2322 BitVector_Word_Insert(reference,offset,count)
2323 BitVector_Object        reference
2324 BitVector_Scalar        offset
2325 BitVector_Scalar        count
2326 CODE:
2327 {
2328     BitVector_Handle  handle;
2329     BitVector_Address address;
2330     N_int off;
2331     N_int cnt;
2332
2333     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2334     {
2335         if ( BIT_VECTOR_SCALAR(offset,N_int,off) &&
2336              BIT_VECTOR_SCALAR(count,N_int,cnt) )
2337         {
2338             if (off < size_(address))
2339             {
2340                 BitVector_Word_Insert(address,off,cnt,true);
2341             }
2342             else BIT_VECTOR_OFFSET_ERROR;
2343         }
2344         else BIT_VECTOR_SCALAR_ERROR;
2345     }
2346     else BIT_VECTOR_OBJECT_ERROR;
2347 }
2348
2349
2350 void
2351 BitVector_Word_Delete(reference,offset,count)
2352 BitVector_Object        reference
2353 BitVector_Scalar        offset
2354 BitVector_Scalar        count
2355 CODE:
2356 {
2357     BitVector_Handle  handle;
2358     BitVector_Address address;
2359     N_int off;
2360     N_int cnt;
2361
2362     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2363     {
2364         if ( BIT_VECTOR_SCALAR(offset,N_int,off) &&
2365              BIT_VECTOR_SCALAR(count,N_int,cnt) )
2366         {
2367             if (off < size_(address))
2368             {
2369                 BitVector_Word_Delete(address,off,cnt,true);
2370             }
2371             else BIT_VECTOR_OFFSET_ERROR;
2372         }
2373         else BIT_VECTOR_SCALAR_ERROR;
2374     }
2375     else BIT_VECTOR_OBJECT_ERROR;
2376 }
2377
2378
2379 void
2380 BitVector_Chunk_Store(reference,chunksize,offset,value)
2381 BitVector_Object        reference
2382 BitVector_Scalar        chunksize
2383 BitVector_Scalar        offset
2384 BitVector_Scalar        value
2385 CODE:
2386 {
2387     BitVector_Handle  handle;
2388     BitVector_Address address;
2389     N_int bits;
2390     N_int off;
2391     N_long val;
2392
2393     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2394     {
2395         if ( BIT_VECTOR_SCALAR(chunksize,N_int,bits) &&
2396              BIT_VECTOR_SCALAR(offset,N_int,off) &&
2397              BIT_VECTOR_SCALAR(value,N_long,val) )
2398         {
2399             if ((bits > 0) and (bits <= BitVector_Long_Bits()))
2400             {
2401                 if (off < bits_(address))
2402                 {
2403                     BitVector_Chunk_Store(address,bits,off,val);
2404                 }
2405                 else BIT_VECTOR_OFFSET_ERROR;
2406             }
2407             else BIT_VECTOR_CHUNK_ERROR;
2408         }
2409         else BIT_VECTOR_SCALAR_ERROR;
2410     }
2411     else BIT_VECTOR_OBJECT_ERROR;
2412 }
2413
2414
2415 N_long
2416 BitVector_Chunk_Read(reference,chunksize,offset)
2417 BitVector_Object        reference
2418 BitVector_Scalar        chunksize
2419 BitVector_Scalar        offset
2420 CODE:
2421 {
2422     BitVector_Handle  handle;
2423     BitVector_Address address;
2424     N_int bits;
2425     N_int off;
2426
2427     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2428     {
2429         if ( BIT_VECTOR_SCALAR(chunksize,N_int,bits) &&
2430              BIT_VECTOR_SCALAR(offset,N_int,off) )
2431         {
2432             if ((bits > 0) and (bits <= BitVector_Long_Bits()))
2433             {
2434                 if (off < bits_(address))
2435                 {
2436                     RETVAL = BitVector_Chunk_Read(address,bits,off);
2437                 }
2438                 else BIT_VECTOR_OFFSET_ERROR;
2439             }
2440             else BIT_VECTOR_CHUNK_ERROR;
2441         }
2442         else BIT_VECTOR_SCALAR_ERROR;
2443     }
2444     else BIT_VECTOR_OBJECT_ERROR;
2445 }
2446 OUTPUT:
2447 RETVAL
2448
2449
2450 void
2451 BitVector_Chunk_List_Store(reference,chunksize,...)
2452 BitVector_Object        reference
2453 BitVector_Scalar        chunksize
2454 CODE:
2455 {
2456     BitVector_Handle  handle;
2457     BitVector_Address address;
2458     BitVector_Scalar  scalar;
2459     N_int chunkspan;
2460     N_long chunkmask;
2461     N_long mask;
2462     N_long chunk;
2463     N_long value;
2464     N_int chunkbits;
2465     N_int wordbits;
2466     N_int wordsize;
2467     N_int offset;
2468     N_int size;
2469     N_int bits;
2470     I32 index;
2471
2472     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2473     {
2474         if ( BIT_VECTOR_SCALAR(chunksize,N_int,chunkspan) )
2475         {
2476             if ((chunkspan > 0) and (chunkspan <= BitVector_Long_Bits()))
2477             {
2478                 wordsize = BitVector_Word_Bits();
2479                 size = size_(address);
2480                 chunkmask = ~((~0L << (chunkspan-1)) << 1); /* C bug work-around */
2481                 chunk = 0L;
2482                 value = 0L;
2483                 index = 2;
2484                 offset = 0;
2485                 wordbits = 0;
2486                 chunkbits = 0;
2487                 while (offset < size)
2488                 {
2489                     if ((chunkbits == 0) and (index < items))
2490                     {
2491                         scalar = ST(index);
2492                         if ( BIT_VECTOR_SCALAR(scalar,N_long,chunk) )
2493                         {
2494                             chunk &= chunkmask;
2495                             chunkbits = chunkspan;
2496                             index++;
2497                         }
2498                         else BIT_VECTOR_SCALAR_ERROR;
2499                     }
2500                     bits = wordsize - wordbits;
2501                     if (chunkbits <= bits)
2502                     {
2503                         chunk <<= wordbits;
2504                         value |= chunk;
2505                         wordbits += chunkbits;
2506                         chunk = 0L;
2507                         chunkbits = 0;
2508                     }
2509                     else
2510                     {
2511                         mask = ~(~0L << bits);
2512                         mask &= chunk;
2513                         mask <<= wordbits;
2514                         value |= mask;
2515                         wordbits += bits;
2516                         chunk >>= bits;
2517                         chunkbits -= bits;
2518                     }
2519                     if ((wordbits >= wordsize) or (index >= items))
2520                     {
2521                         BitVector_Word_Store(address,offset,(N_int)value);
2522                         value = 0L;
2523                         wordbits = 0;
2524                         offset++;
2525                     }
2526                 }
2527             }
2528             else BIT_VECTOR_CHUNK_ERROR;
2529         }
2530         else BIT_VECTOR_SCALAR_ERROR;
2531     }
2532     else BIT_VECTOR_OBJECT_ERROR;
2533 }
2534
2535
2536 void
2537 BitVector_Chunk_List_Read(reference,chunksize)
2538 BitVector_Object        reference
2539 BitVector_Scalar        chunksize
2540 PPCODE:
2541 {
2542     BitVector_Handle  handle;
2543     BitVector_Address address;
2544     N_int chunkspan;
2545     N_long chunk;
2546     N_long value;
2547     N_long mask;
2548     N_int chunkbits;
2549     N_int wordbits;
2550     N_int wordsize;
2551     N_int length;
2552     N_int index;
2553     N_int offset;
2554     N_int size;
2555     N_int bits;
2556
2557     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2558     {
2559         if ( BIT_VECTOR_SCALAR(chunksize,N_int,chunkspan) )
2560         {
2561             if ((chunkspan > 0) and (chunkspan <= BitVector_Long_Bits()))
2562             {
2563                 wordsize = BitVector_Word_Bits();
2564                 bits = bits_(address);
2565                 size = size_(address);
2566                 length = (N_int) (bits / chunkspan);
2567                 if ((length * chunkspan) < bits) length++;
2568                 EXTEND(sp,(int)length);
2569                 chunk = 0L;
2570                 value = 0L;
2571                 index = 0;
2572                 offset = 0;
2573                 wordbits = 0;
2574                 chunkbits = 0;
2575                 while (index < length)
2576                 {
2577                     if ((wordbits == 0) and (offset < size))
2578                     {
2579                         value = (N_long) BitVector_Word_Read(address,offset);
2580                         wordbits = wordsize;
2581                         offset++;
2582                     }
2583                     bits = chunkspan - chunkbits;
2584                     if (wordbits <= bits)
2585                     {
2586                         value <<= chunkbits;
2587                         chunk |= value;
2588                         chunkbits += wordbits;
2589                         value = 0L;
2590                         wordbits = 0;
2591                     }
2592                     else
2593                     {
2594                         mask = ~(~0L << bits);
2595                         mask &= value;
2596                         mask <<= chunkbits;
2597                         chunk |= mask;
2598                         chunkbits += bits;
2599                         value >>= bits;
2600                         wordbits -= bits;
2601                     }
2602                     if ((chunkbits >= chunkspan) or
2603                         ((offset >= size) and (chunkbits > 0)))
2604                     {
2605                         PUSHs(sv_2mortal(newSViv((IV)chunk)));
2606                         chunk = 0L;
2607                         chunkbits = 0;
2608                         index++;
2609                     }
2610                 }
2611             }
2612             else BIT_VECTOR_CHUNK_ERROR;
2613         }
2614         else BIT_VECTOR_SCALAR_ERROR;
2615     }
2616     else BIT_VECTOR_OBJECT_ERROR;
2617 }
2618
2619
2620 void
2621 BitVector_Index_List_Remove(reference,...)
2622 BitVector_Object        reference
2623 CODE:
2624 {
2625     BitVector_Handle  handle;
2626     BitVector_Address address;
2627     BitVector_Scalar  scalar;
2628     N_int value;
2629     N_int bits;
2630     I32 index;
2631
2632     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2633     {
2634         bits = bits_(address);
2635         for ( index = 1; index < items; index++ )
2636         {
2637             scalar = ST(index);
2638             if ( BIT_VECTOR_SCALAR(scalar,N_int,value) )
2639             {
2640                 if (value < bits)
2641                 {
2642                     BitVector_Bit_Off(address,value);
2643                 }
2644                 else BIT_VECTOR_INDEX_ERROR;
2645             }
2646             else BIT_VECTOR_SCALAR_ERROR;
2647         }
2648     }
2649     else BIT_VECTOR_OBJECT_ERROR;
2650 }
2651
2652
2653 void
2654 BitVector_Index_List_Store(reference,...)
2655 BitVector_Object        reference
2656 CODE:
2657 {
2658     BitVector_Handle  handle;
2659     BitVector_Address address;
2660     BitVector_Scalar  scalar;
2661     N_int value;
2662     N_int bits;
2663     I32 index;
2664
2665     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2666     {
2667         bits = bits_(address);
2668         for ( index = 1; index < items; index++ )
2669         {
2670             scalar = ST(index);
2671             if ( BIT_VECTOR_SCALAR(scalar,N_int,value) )
2672             {
2673                 if (value < bits)
2674                 {
2675                     BitVector_Bit_On(address,value);
2676                 }
2677                 else BIT_VECTOR_INDEX_ERROR;
2678             }
2679             else BIT_VECTOR_SCALAR_ERROR;
2680         }
2681     }
2682     else BIT_VECTOR_OBJECT_ERROR;
2683 }
2684
2685
2686 void
2687 BitVector_Index_List_Read(reference)
2688 BitVector_Object        reference
2689 PPCODE:
2690 {
2691     BitVector_Handle  handle;
2692     BitVector_Address address;
2693     N_int size;
2694     N_int bits;
2695     N_int norm;
2696     N_int base;
2697     N_int word;
2698     N_int index;
2699     N_int value;
2700
2701     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2702     {
2703         size = size_(address);
2704         bits = BitVector_Word_Bits();
2705         norm = Set_Norm(address);
2706         if (norm > 0)
2707         {
2708             EXTEND(sp,(int)norm);
2709             for ( base = word = 0; word < size; word++, base += bits )
2710             {
2711                 index = base;
2712                 value = BitVector_Word_Read(address,word);
2713                 while (value)
2714                 {
2715                     if (value AND 0x0001)
2716                       PUSHs(sv_2mortal(newSViv((IV)index)));
2717                     value >>= 1;
2718                     index++;
2719                 }
2720             }
2721         }
2722     }
2723     else BIT_VECTOR_OBJECT_ERROR;
2724 }
2725
2726
2727 MODULE = Bit::Vector            PACKAGE = Bit::Vector           PREFIX = Set_
2728
2729
2730 void
2731 Set_Union(Xref,Yref,Zref)
2732 BitVector_Object        Xref
2733 BitVector_Object        Yref
2734 BitVector_Object        Zref
2735 ALIAS:
2736   Or = 1
2737 CODE:
2738 {
2739     BitVector_Handle  Xhdl;
2740     BitVector_Address Xadr;
2741     BitVector_Handle  Yhdl;
2742     BitVector_Address Yadr;
2743     BitVector_Handle  Zhdl;
2744     BitVector_Address Zadr;
2745
2746     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2747          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2748          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2749     {
2750         if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
2751         {
2752             Set_Union(Xadr,Yadr,Zadr);
2753         }
2754         else BIT_VECTOR_SET_ERROR;
2755     }
2756     else BIT_VECTOR_OBJECT_ERROR;
2757 }
2758
2759
2760 void
2761 Set_Intersection(Xref,Yref,Zref)
2762 BitVector_Object        Xref
2763 BitVector_Object        Yref
2764 BitVector_Object        Zref
2765 ALIAS:
2766   And = 1
2767 CODE:
2768 {
2769     BitVector_Handle  Xhdl;
2770     BitVector_Address Xadr;
2771     BitVector_Handle  Yhdl;
2772     BitVector_Address Yadr;
2773     BitVector_Handle  Zhdl;
2774     BitVector_Address Zadr;
2775
2776     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2777          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2778          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2779     {
2780         if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
2781         {
2782             Set_Intersection(Xadr,Yadr,Zadr);
2783         }
2784         else BIT_VECTOR_SET_ERROR;
2785     }
2786     else BIT_VECTOR_OBJECT_ERROR;
2787 }
2788
2789
2790 void
2791 Set_Difference(Xref,Yref,Zref)
2792 BitVector_Object        Xref
2793 BitVector_Object        Yref
2794 BitVector_Object        Zref
2795 ALIAS:
2796   AndNot = 1
2797 CODE:
2798 {
2799     BitVector_Handle  Xhdl;
2800     BitVector_Address Xadr;
2801     BitVector_Handle  Yhdl;
2802     BitVector_Address Yadr;
2803     BitVector_Handle  Zhdl;
2804     BitVector_Address Zadr;
2805
2806     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2807          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2808          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2809     {
2810         if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
2811         {
2812             Set_Difference(Xadr,Yadr,Zadr);
2813         }
2814         else BIT_VECTOR_SET_ERROR;
2815     }
2816     else BIT_VECTOR_OBJECT_ERROR;
2817 }
2818
2819
2820 void
2821 Set_ExclusiveOr(Xref,Yref,Zref)
2822 BitVector_Object        Xref
2823 BitVector_Object        Yref
2824 BitVector_Object        Zref
2825 ALIAS:
2826   Xor = 1
2827 CODE:
2828 {
2829     BitVector_Handle  Xhdl;
2830     BitVector_Address Xadr;
2831     BitVector_Handle  Yhdl;
2832     BitVector_Address Yadr;
2833     BitVector_Handle  Zhdl;
2834     BitVector_Address Zadr;
2835
2836     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2837          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
2838          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
2839     {
2840         if ((bits_(Xadr) == bits_(Yadr)) and (bits_(Xadr) == bits_(Zadr)))
2841         {
2842             Set_ExclusiveOr(Xadr,Yadr,Zadr);
2843         }
2844         else BIT_VECTOR_SET_ERROR;
2845     }
2846     else BIT_VECTOR_OBJECT_ERROR;
2847 }
2848
2849
2850 void
2851 Set_Complement(Xref,Yref)
2852 BitVector_Object        Xref
2853 BitVector_Object        Yref
2854 ALIAS:
2855   Not = 1
2856 CODE:
2857 {
2858     BitVector_Handle  Xhdl;
2859     BitVector_Address Xadr;
2860     BitVector_Handle  Yhdl;
2861     BitVector_Address Yadr;
2862
2863     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2864          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
2865     {
2866         if (bits_(Xadr) == bits_(Yadr))
2867         {
2868             Set_Complement(Xadr,Yadr);
2869         }
2870         else BIT_VECTOR_SET_ERROR;
2871     }
2872     else BIT_VECTOR_OBJECT_ERROR;
2873 }
2874
2875
2876 boolean
2877 Set_subset(Xref,Yref)
2878 BitVector_Object        Xref
2879 BitVector_Object        Yref
2880 ALIAS:
2881   inclusion = 2
2882 CODE:
2883 {
2884     BitVector_Handle  Xhdl;
2885     BitVector_Address Xadr;
2886     BitVector_Handle  Yhdl;
2887     BitVector_Address Yadr;
2888
2889     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
2890          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
2891     {
2892         if (bits_(Xadr) == bits_(Yadr))
2893         {
2894             RETVAL = Set_subset(Xadr,Yadr);
2895         }
2896         else BIT_VECTOR_SET_ERROR;
2897     }
2898     else BIT_VECTOR_OBJECT_ERROR;
2899 }
2900 OUTPUT:
2901 RETVAL
2902
2903
2904 N_int
2905 Set_Norm(reference)
2906 BitVector_Object        reference
2907 CODE:
2908 {
2909     BitVector_Handle  handle;
2910     BitVector_Address address;
2911
2912     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2913     {
2914         RETVAL = Set_Norm(address);
2915     }
2916     else BIT_VECTOR_OBJECT_ERROR;
2917 }
2918 OUTPUT:
2919 RETVAL
2920
2921
2922 N_int
2923 Set_Norm2(reference)
2924 BitVector_Object        reference
2925 CODE:
2926 {
2927     BitVector_Handle  handle;
2928     BitVector_Address address;
2929
2930     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2931     {
2932         RETVAL = Set_Norm2(address);
2933     }
2934     else BIT_VECTOR_OBJECT_ERROR;
2935 }
2936 OUTPUT:
2937 RETVAL
2938
2939
2940 N_int
2941 Set_Norm3(reference)
2942 BitVector_Object        reference
2943 CODE:
2944 {
2945     BitVector_Handle  handle;
2946     BitVector_Address address;
2947
2948     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2949     {
2950         RETVAL = Set_Norm3(address);
2951     }
2952     else BIT_VECTOR_OBJECT_ERROR;
2953 }
2954 OUTPUT:
2955 RETVAL
2956
2957
2958 Z_long
2959 Set_Min(reference)
2960 BitVector_Object        reference
2961 CODE:
2962 {
2963     BitVector_Handle  handle;
2964     BitVector_Address address;
2965
2966     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2967     {
2968         RETVAL = Set_Min(address);
2969     }
2970     else BIT_VECTOR_OBJECT_ERROR;
2971 }
2972 OUTPUT:
2973 RETVAL
2974
2975
2976 Z_long
2977 Set_Max(reference)
2978 BitVector_Object        reference
2979 CODE:
2980 {
2981     BitVector_Handle  handle;
2982     BitVector_Address address;
2983
2984     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
2985     {
2986         RETVAL = Set_Max(address);
2987     }
2988     else BIT_VECTOR_OBJECT_ERROR;
2989 }
2990 OUTPUT:
2991 RETVAL
2992
2993
2994 MODULE = Bit::Vector            PACKAGE = Bit::Vector           PREFIX = Matrix_
2995
2996
2997 void
2998 Matrix_Multiplication(Xref,Xrows,Xcols,Yref,Yrows,Ycols,Zref,Zrows,Zcols)
2999 BitVector_Object        Xref
3000 BitVector_Scalar        Xrows
3001 BitVector_Scalar        Xcols
3002 BitVector_Object        Yref
3003 BitVector_Scalar        Yrows
3004 BitVector_Scalar        Ycols
3005 BitVector_Object        Zref
3006 BitVector_Scalar        Zrows
3007 BitVector_Scalar        Zcols
3008 CODE:
3009 {
3010     BitVector_Handle  Xhdl;
3011     BitVector_Address Xadr;
3012     BitVector_Handle  Yhdl;
3013     BitVector_Address Yadr;
3014     BitVector_Handle  Zhdl;
3015     BitVector_Address Zadr;
3016     N_int rowsX;
3017     N_int colsX;
3018     N_int rowsY;
3019     N_int colsY;
3020     N_int rowsZ;
3021     N_int colsZ;
3022
3023     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
3024          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
3025          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
3026     {
3027         if ( BIT_VECTOR_SCALAR(Xrows,N_int,rowsX) &&
3028              BIT_VECTOR_SCALAR(Xcols,N_int,colsX) &&
3029              BIT_VECTOR_SCALAR(Yrows,N_int,rowsY) &&
3030              BIT_VECTOR_SCALAR(Ycols,N_int,colsY) &&
3031              BIT_VECTOR_SCALAR(Zrows,N_int,rowsZ) &&
3032              BIT_VECTOR_SCALAR(Zcols,N_int,colsZ) )
3033         {
3034             if ((colsY == rowsZ) and (rowsX == rowsY) and (colsX == colsZ) and
3035                 (bits_(Xadr) == rowsX*colsX) and
3036                 (bits_(Yadr) == rowsY*colsY) and
3037                 (bits_(Zadr) == rowsZ*colsZ))
3038             {
3039                 Matrix_Multiplication(Xadr,rowsX,colsX,
3040                                       Yadr,rowsY,colsY,
3041                                       Zadr,rowsZ,colsZ);
3042             }
3043             else BIT_VECTOR_MATRIX_ERROR;
3044         }
3045         else BIT_VECTOR_SCALAR_ERROR;
3046     }
3047     else BIT_VECTOR_OBJECT_ERROR;
3048 }
3049
3050
3051 void
3052 Matrix_Product(Xref,Xrows,Xcols,Yref,Yrows,Ycols,Zref,Zrows,Zcols)
3053 BitVector_Object        Xref
3054 BitVector_Scalar        Xrows
3055 BitVector_Scalar        Xcols
3056 BitVector_Object        Yref
3057 BitVector_Scalar        Yrows
3058 BitVector_Scalar        Ycols
3059 BitVector_Object        Zref
3060 BitVector_Scalar        Zrows
3061 BitVector_Scalar        Zcols
3062 CODE:
3063 {
3064     BitVector_Handle  Xhdl;
3065     BitVector_Address Xadr;
3066     BitVector_Handle  Yhdl;
3067     BitVector_Address Yadr;
3068     BitVector_Handle  Zhdl;
3069     BitVector_Address Zadr;
3070     N_int rowsX;
3071     N_int colsX;
3072     N_int rowsY;
3073     N_int colsY;
3074     N_int rowsZ;
3075     N_int colsZ;
3076
3077     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
3078          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) &&
3079          BIT_VECTOR_OBJECT(Zref,Zhdl,Zadr) )
3080     {
3081         if ( BIT_VECTOR_SCALAR(Xrows,N_int,rowsX) &&
3082              BIT_VECTOR_SCALAR(Xcols,N_int,colsX) &&
3083              BIT_VECTOR_SCALAR(Yrows,N_int,rowsY) &&
3084              BIT_VECTOR_SCALAR(Ycols,N_int,colsY) &&
3085              BIT_VECTOR_SCALAR(Zrows,N_int,rowsZ) &&
3086              BIT_VECTOR_SCALAR(Zcols,N_int,colsZ) )
3087         {
3088             if ((colsY == rowsZ) and (rowsX == rowsY) and (colsX == colsZ) and
3089                 (bits_(Xadr) == rowsX*colsX) and
3090                 (bits_(Yadr) == rowsY*colsY) and
3091                 (bits_(Zadr) == rowsZ*colsZ))
3092             {
3093                 Matrix_Product(Xadr,rowsX,colsX,
3094                                Yadr,rowsY,colsY,
3095                                Zadr,rowsZ,colsZ);
3096             }
3097             else BIT_VECTOR_MATRIX_ERROR;
3098         }
3099         else BIT_VECTOR_SCALAR_ERROR;
3100     }
3101     else BIT_VECTOR_OBJECT_ERROR;
3102 }
3103
3104
3105 void
3106 Matrix_Closure(reference,rows,cols)
3107 BitVector_Object        reference
3108 BitVector_Scalar        rows
3109 BitVector_Scalar        cols
3110 CODE:
3111 {
3112     BitVector_Handle  handle;
3113     BitVector_Address address;
3114     N_int r;
3115     N_int c;
3116
3117     if ( BIT_VECTOR_OBJECT(reference,handle,address) )
3118     {
3119         if ( BIT_VECTOR_SCALAR(rows,N_int,r) &&
3120              BIT_VECTOR_SCALAR(cols,N_int,c) )
3121         {
3122             if (bits_(address) == r*c)
3123             {
3124                 if (r == c)
3125                 {
3126                     Matrix_Closure(address,r,c);
3127                 }
3128                 else BIT_VECTOR_SHAPE_ERROR;
3129             }
3130             else BIT_VECTOR_MATRIX_ERROR;
3131         }
3132         else BIT_VECTOR_SCALAR_ERROR;
3133     }
3134     else BIT_VECTOR_OBJECT_ERROR;
3135 }
3136
3137
3138 void
3139 Matrix_Transpose(Xref,Xrows,Xcols,Yref,Yrows,Ycols)
3140 BitVector_Object        Xref
3141 BitVector_Scalar        Xrows
3142 BitVector_Scalar        Xcols
3143 BitVector_Object        Yref
3144 BitVector_Scalar        Yrows
3145 BitVector_Scalar        Ycols
3146 CODE:
3147 {
3148     BitVector_Handle  Xhdl;
3149     BitVector_Address Xadr;
3150     BitVector_Handle  Yhdl;
3151     BitVector_Address Yadr;
3152     N_int rowsX;
3153     N_int colsX;
3154     N_int rowsY;
3155     N_int colsY;
3156
3157     if ( BIT_VECTOR_OBJECT(Xref,Xhdl,Xadr) &&
3158          BIT_VECTOR_OBJECT(Yref,Yhdl,Yadr) )
3159     {
3160         if ( BIT_VECTOR_SCALAR(Xrows,N_int,rowsX) &&
3161              BIT_VECTOR_SCALAR(Xcols,N_int,colsX) &&
3162              BIT_VECTOR_SCALAR(Yrows,N_int,rowsY) &&
3163              BIT_VECTOR_SCALAR(Ycols,N_int,colsY) )
3164         {
3165             if ((rowsX == colsY) and (colsX == rowsY) and
3166                 (bits_(Xadr) == rowsX*colsX) and
3167                 (bits_(Yadr) == rowsY*colsY))
3168             {
3169                 if ((Xadr != Yadr) or (rowsY == colsY))
3170                 {
3171                     Matrix_Transpose(Xadr,rowsX,colsX,
3172                                      Yadr,rowsY,colsY);
3173                 }
3174                 else BIT_VECTOR_SHAPE_ERROR;
3175             }
3176             else BIT_VECTOR_MATRIX_ERROR;
3177         }
3178         else BIT_VECTOR_SCALAR_ERROR;
3179     }
3180     else BIT_VECTOR_OBJECT_ERROR;
3181 }
3182
3183