root/psad/tags/psad-2.1.2/Bit-Vector/Vector.xs

Revision 1175, 71.8 kB (checked in by mbr, 4 years ago)

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1
2
3 /*****************************************************************************/
4 /*                                                                           */
5 /*    Copyright (c) 1995 - 2002 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;