1 /* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 #include "libguile/_scm.h"
29 #include "libguile/__scm.h"
30 #include "libguile/smob.h"
31 #include "libguile/strings.h"
32 #include "libguile/array-handle.h"
33 #include "libguile/bitvectors.h"
34 #include "libguile/arrays.h"
35 #include "libguile/vectors.h"
36 #include "libguile/srfi-4.h"
38 /* Bit vectors. Would be nice if they were implemented on top of bytevectors,
39 * but alack, all we have is this crufty C.
42 static scm_t_bits scm_tc16_bitvector
;
44 #define IS_BITVECTOR(obj) SCM_SMOB_PREDICATE(scm_tc16_bitvector,(obj))
45 #define BITVECTOR_BITS(obj) ((scm_t_uint32 *)SCM_SMOB_DATA(obj))
46 #define BITVECTOR_LENGTH(obj) ((size_t)SCM_SMOB_DATA_2(obj))
49 bitvector_free (SCM vec
)
51 scm_gc_free (BITVECTOR_BITS (vec
),
52 sizeof (scm_t_uint32
) * ((BITVECTOR_LENGTH (vec
)+31)/32),
58 bitvector_print (SCM vec
, SCM port
, scm_print_state
*pstate
)
60 size_t bit_len
= BITVECTOR_LENGTH (vec
);
61 size_t word_len
= (bit_len
+31)/32;
62 scm_t_uint32
*bits
= BITVECTOR_BITS (vec
);
65 scm_puts ("#*", port
);
66 for (i
= 0; i
< word_len
; i
++, bit_len
-= 32)
68 scm_t_uint32 mask
= 1;
69 for (j
= 0; j
< 32 && j
< bit_len
; j
++, mask
<<= 1)
70 scm_putc ((bits
[i
] & mask
)? '1' : '0', port
);
77 bitvector_equalp (SCM vec1
, SCM vec2
)
79 size_t bit_len
= BITVECTOR_LENGTH (vec1
);
80 size_t word_len
= (bit_len
+ 31) / 32;
81 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- bit_len
);
82 scm_t_uint32
*bits1
= BITVECTOR_BITS (vec1
);
83 scm_t_uint32
*bits2
= BITVECTOR_BITS (vec2
);
86 if (BITVECTOR_LENGTH (vec2
) != bit_len
)
88 /* avoid underflow in word_len-1 below. */
91 /* compare full words */
92 if (memcmp (bits1
, bits2
, sizeof (scm_t_uint32
) * (word_len
-1)))
94 /* compare partial last words */
95 if ((bits1
[word_len
-1] & last_mask
) != (bits2
[word_len
-1] & last_mask
))
101 scm_is_bitvector (SCM vec
)
103 return IS_BITVECTOR (vec
);
106 SCM_DEFINE (scm_bitvector_p
, "bitvector?", 1, 0, 0,
108 "Return @code{#t} when @var{obj} is a bitvector, else\n"
110 #define FUNC_NAME s_scm_bitvector_p
112 return scm_from_bool (scm_is_bitvector (obj
));
117 scm_c_make_bitvector (size_t len
, SCM fill
)
119 size_t word_len
= (len
+ 31) / 32;
123 bits
= scm_gc_malloc (sizeof (scm_t_uint32
) * word_len
,
125 SCM_NEWSMOB2 (res
, scm_tc16_bitvector
, bits
, len
);
127 if (!SCM_UNBNDP (fill
))
128 scm_bitvector_fill_x (res
, fill
);
133 SCM_DEFINE (scm_make_bitvector
, "make-bitvector", 1, 1, 0,
135 "Create a new bitvector of length @var{len} and\n"
136 "optionally initialize all elements to @var{fill}.")
137 #define FUNC_NAME s_scm_make_bitvector
139 return scm_c_make_bitvector (scm_to_size_t (len
), fill
);
143 SCM_DEFINE (scm_bitvector
, "bitvector", 0, 0, 1,
145 "Create a new bitvector with the arguments as elements.")
146 #define FUNC_NAME s_scm_bitvector
148 return scm_list_to_bitvector (bits
);
153 scm_c_bitvector_length (SCM vec
)
155 scm_assert_smob_type (scm_tc16_bitvector
, vec
);
156 return BITVECTOR_LENGTH (vec
);
159 SCM_DEFINE (scm_bitvector_length
, "bitvector-length", 1, 0, 0,
161 "Return the length of the bitvector @var{vec}.")
162 #define FUNC_NAME s_scm_bitvector_length
164 return scm_from_size_t (scm_c_bitvector_length (vec
));
169 scm_array_handle_bit_elements (scm_t_array_handle
*h
)
171 return scm_array_handle_bit_writable_elements (h
);
175 scm_array_handle_bit_writable_elements (scm_t_array_handle
*h
)
178 if (SCM_I_ARRAYP (vec
))
179 vec
= SCM_I_ARRAY_V (vec
);
180 if (IS_BITVECTOR (vec
))
181 return BITVECTOR_BITS (vec
) + h
->base
/32;
182 scm_wrong_type_arg_msg (NULL
, 0, h
->array
, "bit array");
186 scm_array_handle_bit_elements_offset (scm_t_array_handle
*h
)
192 scm_bitvector_elements (SCM vec
,
193 scm_t_array_handle
*h
,
198 return scm_bitvector_writable_elements (vec
, h
, offp
, lenp
, incp
);
203 scm_bitvector_writable_elements (SCM vec
,
204 scm_t_array_handle
*h
,
209 scm_generalized_vector_get_handle (vec
, h
);
212 scm_t_array_dim
*dim
= scm_array_handle_dims (h
);
213 *offp
= scm_array_handle_bit_elements_offset (h
);
214 *lenp
= dim
->ubnd
- dim
->lbnd
+ 1;
217 return scm_array_handle_bit_writable_elements (h
);
221 scm_c_bitvector_ref (SCM vec
, size_t idx
)
223 scm_t_array_handle handle
;
224 const scm_t_uint32
*bits
;
226 if (IS_BITVECTOR (vec
))
228 if (idx
>= BITVECTOR_LENGTH (vec
))
229 scm_out_of_range (NULL
, scm_from_size_t (idx
));
230 bits
= BITVECTOR_BITS(vec
);
231 return scm_from_bool (bits
[idx
/32] & (1L << (idx
%32)));
239 bits
= scm_bitvector_elements (vec
, &handle
, &off
, &len
, &inc
);
241 scm_out_of_range (NULL
, scm_from_size_t (idx
));
243 res
= scm_from_bool (bits
[idx
/32] & (1L << (idx
%32)));
244 scm_array_handle_release (&handle
);
249 SCM_DEFINE (scm_bitvector_ref
, "bitvector-ref", 2, 0, 0,
251 "Return the element at index @var{idx} of the bitvector\n"
253 #define FUNC_NAME s_scm_bitvector_ref
255 return scm_c_bitvector_ref (vec
, scm_to_size_t (idx
));
260 scm_c_bitvector_set_x (SCM vec
, size_t idx
, SCM val
)
262 scm_t_array_handle handle
;
263 scm_t_uint32
*bits
, mask
;
265 if (IS_BITVECTOR (vec
))
267 if (idx
>= BITVECTOR_LENGTH (vec
))
268 scm_out_of_range (NULL
, scm_from_size_t (idx
));
269 bits
= BITVECTOR_BITS(vec
);
276 bits
= scm_bitvector_writable_elements (vec
, &handle
, &off
, &len
, &inc
);
278 scm_out_of_range (NULL
, scm_from_size_t (idx
));
282 mask
= 1L << (idx
%32);
283 if (scm_is_true (val
))
284 bits
[idx
/32] |= mask
;
286 bits
[idx
/32] &= ~mask
;
288 if (!IS_BITVECTOR (vec
))
289 scm_array_handle_release (&handle
);
292 SCM_DEFINE (scm_bitvector_set_x
, "bitvector-set!", 3, 0, 0,
293 (SCM vec
, SCM idx
, SCM val
),
294 "Set the element at index @var{idx} of the bitvector\n"
295 "@var{vec} when @var{val} is true, else clear it.")
296 #define FUNC_NAME s_scm_bitvector_set_x
298 scm_c_bitvector_set_x (vec
, scm_to_size_t (idx
), val
);
299 return SCM_UNSPECIFIED
;
303 SCM_DEFINE (scm_bitvector_fill_x
, "bitvector-fill!", 2, 0, 0,
305 "Set all elements of the bitvector\n"
306 "@var{vec} when @var{val} is true, else clear them.")
307 #define FUNC_NAME s_scm_bitvector_fill_x
309 scm_t_array_handle handle
;
314 bits
= scm_bitvector_writable_elements (vec
, &handle
,
317 if (off
== 0 && inc
== 1 && len
> 0)
321 size_t word_len
= (len
+ 31) / 32;
322 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
324 if (scm_is_true (val
))
326 memset (bits
, 0xFF, sizeof(scm_t_uint32
)*(word_len
-1));
327 bits
[word_len
-1] |= last_mask
;
331 memset (bits
, 0x00, sizeof(scm_t_uint32
)*(word_len
-1));
332 bits
[word_len
-1] &= ~last_mask
;
338 for (i
= 0; i
< len
; i
++)
339 scm_array_handle_set (&handle
, i
*inc
, val
);
342 scm_array_handle_release (&handle
);
344 return SCM_UNSPECIFIED
;
348 SCM_DEFINE (scm_list_to_bitvector
, "list->bitvector", 1, 0, 0,
350 "Return a new bitvector initialized with the elements\n"
352 #define FUNC_NAME s_scm_list_to_bitvector
354 size_t bit_len
= scm_to_size_t (scm_length (list
));
355 SCM vec
= scm_c_make_bitvector (bit_len
, SCM_UNDEFINED
);
356 size_t word_len
= (bit_len
+31)/32;
357 scm_t_array_handle handle
;
358 scm_t_uint32
*bits
= scm_bitvector_writable_elements (vec
, &handle
,
362 for (i
= 0; i
< word_len
&& scm_is_pair (list
); i
++, bit_len
-= 32)
364 scm_t_uint32 mask
= 1;
366 for (j
= 0; j
< 32 && j
< bit_len
;
367 j
++, mask
<<= 1, list
= SCM_CDR (list
))
368 if (scm_is_true (SCM_CAR (list
)))
372 scm_array_handle_release (&handle
);
378 SCM_DEFINE (scm_bitvector_to_list
, "bitvector->list", 1, 0, 0,
380 "Return a new list initialized with the elements\n"
381 "of the bitvector @var{vec}.")
382 #define FUNC_NAME s_scm_bitvector_to_list
384 scm_t_array_handle handle
;
390 bits
= scm_bitvector_writable_elements (vec
, &handle
,
393 if (off
== 0 && inc
== 1)
397 size_t word_len
= (len
+ 31) / 32;
400 for (i
= 0; i
< word_len
; i
++, len
-= 32)
402 scm_t_uint32 mask
= 1;
403 for (j
= 0; j
< 32 && j
< len
; j
++, mask
<<= 1)
404 res
= scm_cons ((bits
[i
] & mask
)? SCM_BOOL_T
: SCM_BOOL_F
, res
);
410 for (i
= 0; i
< len
; i
++)
411 res
= scm_cons (scm_array_handle_ref (&handle
, i
*inc
), res
);
414 scm_array_handle_release (&handle
);
416 return scm_reverse_x (res
, SCM_EOL
);
420 /* From mmix-arith.w by Knuth.
422 Here's a fun way to count the number of bits in a tetrabyte.
424 [This classical trick is called the ``Gillies--Miller method for
425 sideways addition'' in {\sl The Preparation of Programs for an
426 Electronic Digital Computer\/} by Wilkes, Wheeler, and Gill, second
427 edition (Reading, Mass.:\ Addison--Wesley, 1957), 191--193. Some of
428 the tricks used here were suggested by Balbir Singh, Peter
429 Rossmanith, and Stefan Schwoon.]
433 count_ones (scm_t_uint32 x
)
435 x
=x
-((x
>>1)&0x55555555);
436 x
=(x
&0x33333333)+((x
>>2)&0x33333333);
437 x
=(x
+(x
>>4))&0x0f0f0f0f;
439 return (x
+(x
>>16)) & 0xff;
442 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
443 (SCM b
, SCM bitvector
),
444 "Return the number of occurrences of the boolean @var{b} in\n"
446 #define FUNC_NAME s_scm_bit_count
448 scm_t_array_handle handle
;
452 int bit
= scm_to_bool (b
);
455 bits
= scm_bitvector_writable_elements (bitvector
, &handle
,
458 if (off
== 0 && inc
== 1 && len
> 0)
462 size_t word_len
= (len
+ 31) / 32;
463 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
466 for (i
= 0; i
< word_len
-1; i
++)
467 count
+= count_ones (bits
[i
]);
468 count
+= count_ones (bits
[i
] & last_mask
);
473 for (i
= 0; i
< len
; i
++)
474 if (scm_is_true (scm_array_handle_ref (&handle
, i
*inc
)))
478 scm_array_handle_release (&handle
);
480 return scm_from_size_t (bit
? count
: len
-count
);
484 /* returns 32 for x == 0.
487 find_first_one (scm_t_uint32 x
)
490 /* do a binary search in x. */
491 if ((x
& 0xFFFF) == 0)
504 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
505 (SCM item
, SCM v
, SCM k
),
506 "Return the index of the first occurrance of @var{item} in bit\n"
507 "vector @var{v}, starting from @var{k}. If there is no\n"
508 "@var{item} entry between @var{k} and the end of\n"
509 "@var{bitvector}, then return @code{#f}. For example,\n"
512 "(bit-position #t #*000101 0) @result{} 3\n"
513 "(bit-position #f #*0001111 3) @result{} #f\n"
515 #define FUNC_NAME s_scm_bit_position
517 scm_t_array_handle handle
;
518 size_t off
, len
, first_bit
;
520 const scm_t_uint32
*bits
;
521 int bit
= scm_to_bool (item
);
522 SCM res
= SCM_BOOL_F
;
524 bits
= scm_bitvector_elements (v
, &handle
, &off
, &len
, &inc
);
525 first_bit
= scm_to_unsigned_integer (k
, 0, len
);
527 if (off
== 0 && inc
== 1 && len
> 0)
529 size_t i
, word_len
= (len
+ 31) / 32;
530 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
531 size_t first_word
= first_bit
/ 32;
532 scm_t_uint32 first_mask
=
533 ((scm_t_uint32
)-1) << (first_bit
- 32*first_word
);
536 for (i
= first_word
; i
< word_len
; i
++)
538 w
= (bit
? bits
[i
] : ~bits
[i
]);
545 res
= scm_from_size_t (32*i
+ find_first_one (w
));
553 for (i
= first_bit
; i
< len
; i
++)
555 SCM elt
= scm_array_handle_ref (&handle
, i
*inc
);
556 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
558 res
= scm_from_size_t (i
);
564 scm_array_handle_release (&handle
);
570 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
571 (SCM v
, SCM kv
, SCM obj
),
572 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
573 "selecting the entries to change. The return value is\n"
576 "If @var{kv} is a bit vector, then those entries where it has\n"
577 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
578 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
579 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
580 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
583 "(define bv #*01000010)\n"
584 "(bit-set*! bv #*10010001 #t)\n"
586 "@result{} #*11010011\n"
589 "If @var{kv} is a u32vector, then its elements are\n"
590 "indices into @var{v} which are set to @var{obj}.\n"
593 "(define bv #*01000010)\n"
594 "(bit-set*! bv #u32(5 2 7) #t)\n"
596 "@result{} #*01100111\n"
598 #define FUNC_NAME s_scm_bit_set_star_x
600 scm_t_array_handle v_handle
;
603 scm_t_uint32
*v_bits
;
606 /* Validate that OBJ is a boolean so this is done even if we don't
609 bit
= scm_to_bool (obj
);
611 v_bits
= scm_bitvector_writable_elements (v
, &v_handle
,
612 &v_off
, &v_len
, &v_inc
);
614 if (scm_is_bitvector (kv
))
616 scm_t_array_handle kv_handle
;
617 size_t kv_off
, kv_len
;
619 const scm_t_uint32
*kv_bits
;
621 kv_bits
= scm_bitvector_elements (v
, &kv_handle
,
622 &kv_off
, &kv_len
, &kv_inc
);
625 scm_misc_error (NULL
,
626 "bit vectors must have equal length",
629 if (v_off
== 0 && v_inc
== 1 && kv_off
== 0 && kv_inc
== 1 && kv_len
> 0)
631 size_t word_len
= (kv_len
+ 31) / 32;
632 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- kv_len
);
637 for (i
= 0; i
< word_len
-1; i
++)
638 v_bits
[i
] &= ~kv_bits
[i
];
639 v_bits
[i
] &= ~(kv_bits
[i
] & last_mask
);
643 for (i
= 0; i
< word_len
-1; i
++)
644 v_bits
[i
] |= kv_bits
[i
];
645 v_bits
[i
] |= kv_bits
[i
] & last_mask
;
651 for (i
= 0; i
< kv_len
; i
++)
652 if (scm_is_true (scm_array_handle_ref (&kv_handle
, i
*kv_inc
)))
653 scm_array_handle_set (&v_handle
, i
*v_inc
, obj
);
656 scm_array_handle_release (&kv_handle
);
659 else if (scm_is_true (scm_u32vector_p (kv
)))
661 scm_t_array_handle kv_handle
;
664 const scm_t_uint32
*kv_elts
;
666 kv_elts
= scm_u32vector_elements (kv
, &kv_handle
, &kv_len
, &kv_inc
);
667 for (i
= 0; i
< kv_len
; i
++, kv_elts
+= kv_inc
)
668 scm_array_handle_set (&v_handle
, (*kv_elts
)*v_inc
, obj
);
670 scm_array_handle_release (&kv_handle
);
673 scm_wrong_type_arg_msg (NULL
, 0, kv
, "bitvector or u32vector");
675 scm_array_handle_release (&v_handle
);
677 return SCM_UNSPECIFIED
;
682 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
683 (SCM v
, SCM kv
, SCM obj
),
684 "Return a count of how many entries in bit vector @var{v} are\n"
685 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
688 "If @var{kv} is a bit vector, then those entries where it has\n"
689 "@code{#t} are the ones in @var{v} which are considered.\n"
690 "@var{kv} and @var{v} must be the same length.\n"
692 "If @var{kv} is a u32vector, then it contains\n"
693 "the indexes in @var{v} to consider.\n"
698 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
699 "(bit-count* #*01110111 #u32(7 0 4) #f) @result{} 2\n"
701 #define FUNC_NAME s_scm_bit_count_star
703 scm_t_array_handle v_handle
;
706 const scm_t_uint32
*v_bits
;
710 /* Validate that OBJ is a boolean so this is done even if we don't
713 bit
= scm_to_bool (obj
);
715 v_bits
= scm_bitvector_elements (v
, &v_handle
,
716 &v_off
, &v_len
, &v_inc
);
718 if (scm_is_bitvector (kv
))
720 scm_t_array_handle kv_handle
;
721 size_t kv_off
, kv_len
;
723 const scm_t_uint32
*kv_bits
;
725 kv_bits
= scm_bitvector_elements (v
, &kv_handle
,
726 &kv_off
, &kv_len
, &kv_inc
);
729 scm_misc_error (NULL
,
730 "bit vectors must have equal length",
733 if (v_off
== 0 && v_inc
== 1 && kv_off
== 0 && kv_inc
== 1 && kv_len
> 0)
735 size_t i
, word_len
= (kv_len
+ 31) / 32;
736 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- kv_len
);
737 scm_t_uint32 xor_mask
= bit
? 0 : ((scm_t_uint32
)-1);
739 for (i
= 0; i
< word_len
-1; i
++)
740 count
+= count_ones ((v_bits
[i
]^xor_mask
) & kv_bits
[i
]);
741 count
+= count_ones ((v_bits
[i
]^xor_mask
) & kv_bits
[i
] & last_mask
);
746 for (i
= 0; i
< kv_len
; i
++)
747 if (scm_is_true (scm_array_handle_ref (&kv_handle
, i
)))
749 SCM elt
= scm_array_handle_ref (&v_handle
, i
*v_inc
);
750 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
755 scm_array_handle_release (&kv_handle
);
758 else if (scm_is_true (scm_u32vector_p (kv
)))
760 scm_t_array_handle kv_handle
;
763 const scm_t_uint32
*kv_elts
;
765 kv_elts
= scm_u32vector_elements (kv
, &kv_handle
, &kv_len
, &kv_inc
);
766 for (i
= 0; i
< kv_len
; i
++, kv_elts
+= kv_inc
)
768 SCM elt
= scm_array_handle_ref (&v_handle
, (*kv_elts
)*v_inc
);
769 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
773 scm_array_handle_release (&kv_handle
);
776 scm_wrong_type_arg_msg (NULL
, 0, kv
, "bitvector or u32vector");
778 scm_array_handle_release (&v_handle
);
780 return scm_from_size_t (count
);
784 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
786 "Modify the bit vector @var{v} by replacing each element with\n"
788 #define FUNC_NAME s_scm_bit_invert_x
790 scm_t_array_handle handle
;
795 bits
= scm_bitvector_writable_elements (v
, &handle
, &off
, &len
, &inc
);
797 if (off
== 0 && inc
== 1 && len
> 0)
799 size_t word_len
= (len
+ 31) / 32;
800 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
803 for (i
= 0; i
< word_len
-1; i
++)
805 bits
[i
] = bits
[i
] ^ last_mask
;
810 for (i
= 0; i
< len
; i
++)
811 scm_array_handle_set (&handle
, i
*inc
,
812 scm_not (scm_array_handle_ref (&handle
, i
*inc
)));
815 scm_array_handle_release (&handle
);
817 return SCM_UNSPECIFIED
;
823 scm_istr2bve (SCM str
)
825 scm_t_array_handle handle
;
826 size_t len
= scm_i_string_length (str
);
827 SCM vec
= scm_c_make_bitvector (len
, SCM_UNDEFINED
);
835 data
= scm_bitvector_writable_elements (vec
, &handle
, NULL
, NULL
, NULL
);
836 c_str
= scm_i_string_chars (str
);
838 for (k
= 0; k
< (len
+ 31) / 32; k
++)
844 for (mask
= 1L; j
--; mask
<<= 1)
859 scm_array_handle_release (&handle
);
860 scm_remember_upto_here_1 (str
);
865 scm_init_bitvectors ()
867 scm_tc16_bitvector
= scm_make_smob_type ("bitvector", 0);
868 scm_set_smob_free (scm_tc16_bitvector
, bitvector_free
);
869 scm_set_smob_print (scm_tc16_bitvector
, bitvector_print
);
870 scm_set_smob_equalp (scm_tc16_bitvector
, bitvector_equalp
);
872 #include "libguile/bitvectors.x"