1 /* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009, 2010, 2011 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/generalized-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_print (SCM vec
, SCM port
, scm_print_state
*pstate
)
51 size_t bit_len
= BITVECTOR_LENGTH (vec
);
52 size_t word_len
= (bit_len
+31)/32;
53 scm_t_uint32
*bits
= BITVECTOR_BITS (vec
);
56 scm_puts_unlocked ("#*", port
);
57 for (i
= 0; i
< word_len
; i
++, bit_len
-= 32)
59 scm_t_uint32 mask
= 1;
60 for (j
= 0; j
< 32 && j
< bit_len
; j
++, mask
<<= 1)
61 scm_putc_unlocked ((bits
[i
] & mask
)? '1' : '0', port
);
68 bitvector_equalp (SCM vec1
, SCM vec2
)
70 size_t bit_len
= BITVECTOR_LENGTH (vec1
);
71 size_t word_len
= (bit_len
+ 31) / 32;
72 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- bit_len
);
73 scm_t_uint32
*bits1
= BITVECTOR_BITS (vec1
);
74 scm_t_uint32
*bits2
= BITVECTOR_BITS (vec2
);
77 if (BITVECTOR_LENGTH (vec2
) != bit_len
)
79 /* avoid underflow in word_len-1 below. */
82 /* compare full words */
83 if (memcmp (bits1
, bits2
, sizeof (scm_t_uint32
) * (word_len
-1)))
85 /* compare partial last words */
86 if ((bits1
[word_len
-1] & last_mask
) != (bits2
[word_len
-1] & last_mask
))
92 scm_is_bitvector (SCM vec
)
94 return IS_BITVECTOR (vec
);
97 SCM_DEFINE (scm_bitvector_p
, "bitvector?", 1, 0, 0,
99 "Return @code{#t} when @var{obj} is a bitvector, else\n"
101 #define FUNC_NAME s_scm_bitvector_p
103 return scm_from_bool (scm_is_bitvector (obj
));
108 scm_c_make_bitvector (size_t len
, SCM fill
)
110 size_t word_len
= (len
+ 31) / 32;
114 bits
= scm_gc_malloc_pointerless (sizeof (scm_t_uint32
) * word_len
,
116 SCM_NEWSMOB2 (res
, scm_tc16_bitvector
, bits
, len
);
118 if (!SCM_UNBNDP (fill
))
119 scm_bitvector_fill_x (res
, fill
);
121 memset (bits
, 0, sizeof (scm_t_uint32
) * word_len
);
126 SCM_DEFINE (scm_make_bitvector
, "make-bitvector", 1, 1, 0,
128 "Create a new bitvector of length @var{len} and\n"
129 "optionally initialize all elements to @var{fill}.")
130 #define FUNC_NAME s_scm_make_bitvector
132 return scm_c_make_bitvector (scm_to_size_t (len
), fill
);
136 SCM_DEFINE (scm_bitvector
, "bitvector", 0, 0, 1,
138 "Create a new bitvector with the arguments as elements.")
139 #define FUNC_NAME s_scm_bitvector
141 return scm_list_to_bitvector (bits
);
146 scm_c_bitvector_length (SCM vec
)
148 scm_assert_smob_type (scm_tc16_bitvector
, vec
);
149 return BITVECTOR_LENGTH (vec
);
152 SCM_DEFINE (scm_bitvector_length
, "bitvector-length", 1, 0, 0,
154 "Return the length of the bitvector @var{vec}.")
155 #define FUNC_NAME s_scm_bitvector_length
157 return scm_from_size_t (scm_c_bitvector_length (vec
));
162 scm_array_handle_bit_elements (scm_t_array_handle
*h
)
164 return scm_array_handle_bit_writable_elements (h
);
168 scm_array_handle_bit_writable_elements (scm_t_array_handle
*h
)
171 if (SCM_I_ARRAYP (vec
))
172 vec
= SCM_I_ARRAY_V (vec
);
173 if (IS_BITVECTOR (vec
))
174 return BITVECTOR_BITS (vec
) + h
->base
/32;
175 scm_wrong_type_arg_msg (NULL
, 0, h
->array
, "bit array");
179 scm_array_handle_bit_elements_offset (scm_t_array_handle
*h
)
185 scm_bitvector_elements (SCM vec
,
186 scm_t_array_handle
*h
,
191 return scm_bitvector_writable_elements (vec
, h
, offp
, lenp
, incp
);
196 scm_bitvector_writable_elements (SCM vec
,
197 scm_t_array_handle
*h
,
202 scm_generalized_vector_get_handle (vec
, h
);
205 scm_t_array_dim
*dim
= scm_array_handle_dims (h
);
206 *offp
= scm_array_handle_bit_elements_offset (h
);
207 *lenp
= dim
->ubnd
- dim
->lbnd
+ 1;
210 return scm_array_handle_bit_writable_elements (h
);
214 scm_c_bitvector_ref (SCM vec
, size_t idx
)
216 scm_t_array_handle handle
;
217 const scm_t_uint32
*bits
;
219 if (IS_BITVECTOR (vec
))
221 if (idx
>= BITVECTOR_LENGTH (vec
))
222 scm_out_of_range (NULL
, scm_from_size_t (idx
));
223 bits
= BITVECTOR_BITS(vec
);
224 return scm_from_bool (bits
[idx
/32] & (1L << (idx
%32)));
232 bits
= scm_bitvector_elements (vec
, &handle
, &off
, &len
, &inc
);
234 scm_out_of_range (NULL
, scm_from_size_t (idx
));
236 res
= scm_from_bool (bits
[idx
/32] & (1L << (idx
%32)));
237 scm_array_handle_release (&handle
);
242 SCM_DEFINE (scm_bitvector_ref
, "bitvector-ref", 2, 0, 0,
244 "Return the element at index @var{idx} of the bitvector\n"
246 #define FUNC_NAME s_scm_bitvector_ref
248 return scm_c_bitvector_ref (vec
, scm_to_size_t (idx
));
253 scm_c_bitvector_set_x (SCM vec
, size_t idx
, SCM val
)
255 scm_t_array_handle handle
;
256 scm_t_uint32
*bits
, mask
;
258 if (IS_BITVECTOR (vec
))
260 if (idx
>= BITVECTOR_LENGTH (vec
))
261 scm_out_of_range (NULL
, scm_from_size_t (idx
));
262 bits
= BITVECTOR_BITS(vec
);
269 bits
= scm_bitvector_writable_elements (vec
, &handle
, &off
, &len
, &inc
);
271 scm_out_of_range (NULL
, scm_from_size_t (idx
));
275 mask
= 1L << (idx
%32);
276 if (scm_is_true (val
))
277 bits
[idx
/32] |= mask
;
279 bits
[idx
/32] &= ~mask
;
281 if (!IS_BITVECTOR (vec
))
282 scm_array_handle_release (&handle
);
285 SCM_DEFINE (scm_bitvector_set_x
, "bitvector-set!", 3, 0, 0,
286 (SCM vec
, SCM idx
, SCM val
),
287 "Set the element at index @var{idx} of the bitvector\n"
288 "@var{vec} when @var{val} is true, else clear it.")
289 #define FUNC_NAME s_scm_bitvector_set_x
291 scm_c_bitvector_set_x (vec
, scm_to_size_t (idx
), val
);
292 return SCM_UNSPECIFIED
;
296 SCM_DEFINE (scm_bitvector_fill_x
, "bitvector-fill!", 2, 0, 0,
298 "Set all elements of the bitvector\n"
299 "@var{vec} when @var{val} is true, else clear them.")
300 #define FUNC_NAME s_scm_bitvector_fill_x
302 scm_t_array_handle handle
;
307 bits
= scm_bitvector_writable_elements (vec
, &handle
,
310 if (off
== 0 && inc
== 1 && len
> 0)
314 size_t word_len
= (len
+ 31) / 32;
315 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
317 if (scm_is_true (val
))
319 memset (bits
, 0xFF, sizeof(scm_t_uint32
)*(word_len
-1));
320 bits
[word_len
-1] |= last_mask
;
324 memset (bits
, 0x00, sizeof(scm_t_uint32
)*(word_len
-1));
325 bits
[word_len
-1] &= ~last_mask
;
331 for (i
= 0; i
< len
; i
++)
332 scm_array_handle_set (&handle
, i
*inc
, val
);
335 scm_array_handle_release (&handle
);
337 return SCM_UNSPECIFIED
;
341 SCM_DEFINE (scm_list_to_bitvector
, "list->bitvector", 1, 0, 0,
343 "Return a new bitvector initialized with the elements\n"
345 #define FUNC_NAME s_scm_list_to_bitvector
347 size_t bit_len
= scm_to_size_t (scm_length (list
));
348 SCM vec
= scm_c_make_bitvector (bit_len
, SCM_UNDEFINED
);
349 size_t word_len
= (bit_len
+31)/32;
350 scm_t_array_handle handle
;
351 scm_t_uint32
*bits
= scm_bitvector_writable_elements (vec
, &handle
,
355 for (i
= 0; i
< word_len
&& scm_is_pair (list
); i
++, bit_len
-= 32)
357 scm_t_uint32 mask
= 1;
359 for (j
= 0; j
< 32 && j
< bit_len
;
360 j
++, mask
<<= 1, list
= SCM_CDR (list
))
361 if (scm_is_true (SCM_CAR (list
)))
365 scm_array_handle_release (&handle
);
371 SCM_DEFINE (scm_bitvector_to_list
, "bitvector->list", 1, 0, 0,
373 "Return a new list initialized with the elements\n"
374 "of the bitvector @var{vec}.")
375 #define FUNC_NAME s_scm_bitvector_to_list
377 scm_t_array_handle handle
;
383 bits
= scm_bitvector_writable_elements (vec
, &handle
,
386 if (off
== 0 && inc
== 1)
390 size_t word_len
= (len
+ 31) / 32;
393 for (i
= 0; i
< word_len
; i
++, len
-= 32)
395 scm_t_uint32 mask
= 1;
396 for (j
= 0; j
< 32 && j
< len
; j
++, mask
<<= 1)
397 res
= scm_cons ((bits
[i
] & mask
)? SCM_BOOL_T
: SCM_BOOL_F
, res
);
403 for (i
= 0; i
< len
; i
++)
404 res
= scm_cons (scm_array_handle_ref (&handle
, i
*inc
), res
);
407 scm_array_handle_release (&handle
);
409 return scm_reverse_x (res
, SCM_EOL
);
413 /* From mmix-arith.w by Knuth.
415 Here's a fun way to count the number of bits in a tetrabyte.
417 [This classical trick is called the ``Gillies--Miller method for
418 sideways addition'' in {\sl The Preparation of Programs for an
419 Electronic Digital Computer\/} by Wilkes, Wheeler, and Gill, second
420 edition (Reading, Mass.:\ Addison--Wesley, 1957), 191--193. Some of
421 the tricks used here were suggested by Balbir Singh, Peter
422 Rossmanith, and Stefan Schwoon.]
426 count_ones (scm_t_uint32 x
)
428 x
=x
-((x
>>1)&0x55555555);
429 x
=(x
&0x33333333)+((x
>>2)&0x33333333);
430 x
=(x
+(x
>>4))&0x0f0f0f0f;
432 return (x
+(x
>>16)) & 0xff;
435 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
436 (SCM b
, SCM bitvector
),
437 "Return the number of occurrences of the boolean @var{b} in\n"
439 #define FUNC_NAME s_scm_bit_count
441 scm_t_array_handle handle
;
445 int bit
= scm_to_bool (b
);
448 bits
= scm_bitvector_writable_elements (bitvector
, &handle
,
451 if (off
== 0 && inc
== 1 && len
> 0)
455 size_t word_len
= (len
+ 31) / 32;
456 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
459 for (i
= 0; i
< word_len
-1; i
++)
460 count
+= count_ones (bits
[i
]);
461 count
+= count_ones (bits
[i
] & last_mask
);
466 for (i
= 0; i
< len
; i
++)
467 if (scm_is_true (scm_array_handle_ref (&handle
, i
*inc
)))
471 scm_array_handle_release (&handle
);
473 return scm_from_size_t (bit
? count
: len
-count
);
477 /* returns 32 for x == 0.
480 find_first_one (scm_t_uint32 x
)
483 /* do a binary search in x. */
484 if ((x
& 0xFFFF) == 0)
497 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
498 (SCM item
, SCM v
, SCM k
),
499 "Return the index of the first occurrence of @var{item} in bit\n"
500 "vector @var{v}, starting from @var{k}. If there is no\n"
501 "@var{item} entry between @var{k} and the end of\n"
502 "@var{bitvector}, then return @code{#f}. For example,\n"
505 "(bit-position #t #*000101 0) @result{} 3\n"
506 "(bit-position #f #*0001111 3) @result{} #f\n"
508 #define FUNC_NAME s_scm_bit_position
510 scm_t_array_handle handle
;
511 size_t off
, len
, first_bit
;
513 const scm_t_uint32
*bits
;
514 int bit
= scm_to_bool (item
);
515 SCM res
= SCM_BOOL_F
;
517 bits
= scm_bitvector_elements (v
, &handle
, &off
, &len
, &inc
);
518 first_bit
= scm_to_unsigned_integer (k
, 0, len
);
520 if (off
== 0 && inc
== 1 && len
> 0)
522 size_t i
, word_len
= (len
+ 31) / 32;
523 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
524 size_t first_word
= first_bit
/ 32;
525 scm_t_uint32 first_mask
=
526 ((scm_t_uint32
)-1) << (first_bit
- 32*first_word
);
529 for (i
= first_word
; i
< word_len
; i
++)
531 w
= (bit
? bits
[i
] : ~bits
[i
]);
538 res
= scm_from_size_t (32*i
+ find_first_one (w
));
546 for (i
= first_bit
; i
< len
; i
++)
548 SCM elt
= scm_array_handle_ref (&handle
, i
*inc
);
549 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
551 res
= scm_from_size_t (i
);
557 scm_array_handle_release (&handle
);
563 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
564 (SCM v
, SCM kv
, SCM obj
),
565 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
566 "selecting the entries to change. The return value is\n"
569 "If @var{kv} is a bit vector, then those entries where it has\n"
570 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
571 "@var{v} must be at least as long as @var{kv}. When @var{obj}\n"
572 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
573 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
576 "(define bv #*01000010)\n"
577 "(bit-set*! bv #*10010001 #t)\n"
579 "@result{} #*11010011\n"
582 "If @var{kv} is a u32vector, then its elements are\n"
583 "indices into @var{v} which are set to @var{obj}.\n"
586 "(define bv #*01000010)\n"
587 "(bit-set*! bv #u32(5 2 7) #t)\n"
589 "@result{} #*01100111\n"
591 #define FUNC_NAME s_scm_bit_set_star_x
593 scm_t_array_handle v_handle
;
596 scm_t_uint32
*v_bits
;
599 /* Validate that OBJ is a boolean so this is done even if we don't
602 bit
= scm_to_bool (obj
);
604 v_bits
= scm_bitvector_writable_elements (v
, &v_handle
,
605 &v_off
, &v_len
, &v_inc
);
607 if (scm_is_bitvector (kv
))
609 scm_t_array_handle kv_handle
;
610 size_t kv_off
, kv_len
;
612 const scm_t_uint32
*kv_bits
;
614 kv_bits
= scm_bitvector_elements (kv
, &kv_handle
,
615 &kv_off
, &kv_len
, &kv_inc
);
618 scm_misc_error (NULL
,
619 "bit vectors must have equal length",
622 if (v_off
== 0 && v_inc
== 1 && kv_off
== 0 && kv_inc
== 1 && kv_len
> 0)
624 size_t word_len
= (kv_len
+ 31) / 32;
625 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- kv_len
);
630 for (i
= 0; i
< word_len
-1; i
++)
631 v_bits
[i
] &= ~kv_bits
[i
];
632 v_bits
[i
] &= ~(kv_bits
[i
] & last_mask
);
636 for (i
= 0; i
< word_len
-1; i
++)
637 v_bits
[i
] |= kv_bits
[i
];
638 v_bits
[i
] |= kv_bits
[i
] & last_mask
;
644 for (i
= 0; i
< kv_len
; i
++)
645 if (scm_is_true (scm_array_handle_ref (&kv_handle
, i
*kv_inc
)))
646 scm_array_handle_set (&v_handle
, i
*v_inc
, obj
);
649 scm_array_handle_release (&kv_handle
);
652 else if (scm_is_true (scm_u32vector_p (kv
)))
654 scm_t_array_handle kv_handle
;
657 const scm_t_uint32
*kv_elts
;
659 kv_elts
= scm_u32vector_elements (kv
, &kv_handle
, &kv_len
, &kv_inc
);
660 for (i
= 0; i
< kv_len
; i
++, kv_elts
+= kv_inc
)
661 scm_array_handle_set (&v_handle
, (*kv_elts
)*v_inc
, obj
);
663 scm_array_handle_release (&kv_handle
);
666 scm_wrong_type_arg_msg (NULL
, 0, kv
, "bitvector or u32vector");
668 scm_array_handle_release (&v_handle
);
670 return SCM_UNSPECIFIED
;
675 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
676 (SCM v
, SCM kv
, SCM obj
),
677 "Return a count of how many entries in bit vector @var{v} are\n"
678 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
681 "If @var{kv} is a bit vector, then those entries where it has\n"
682 "@code{#t} are the ones in @var{v} which are considered.\n"
683 "@var{kv} and @var{v} must be the same length.\n"
685 "If @var{kv} is a u32vector, then it contains\n"
686 "the indexes in @var{v} to consider.\n"
691 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
692 "(bit-count* #*01110111 #u32(7 0 4) #f) @result{} 2\n"
694 #define FUNC_NAME s_scm_bit_count_star
696 scm_t_array_handle v_handle
;
699 const scm_t_uint32
*v_bits
;
703 /* Validate that OBJ is a boolean so this is done even if we don't
706 bit
= scm_to_bool (obj
);
708 v_bits
= scm_bitvector_elements (v
, &v_handle
,
709 &v_off
, &v_len
, &v_inc
);
711 if (scm_is_bitvector (kv
))
713 scm_t_array_handle kv_handle
;
714 size_t kv_off
, kv_len
;
716 const scm_t_uint32
*kv_bits
;
718 kv_bits
= scm_bitvector_elements (v
, &kv_handle
,
719 &kv_off
, &kv_len
, &kv_inc
);
722 scm_misc_error (NULL
,
723 "bit vectors must have equal length",
726 if (v_off
== 0 && v_inc
== 1 && kv_off
== 0 && kv_inc
== 1 && kv_len
> 0)
728 size_t i
, word_len
= (kv_len
+ 31) / 32;
729 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- kv_len
);
730 scm_t_uint32 xor_mask
= bit
? 0 : ((scm_t_uint32
)-1);
732 for (i
= 0; i
< word_len
-1; i
++)
733 count
+= count_ones ((v_bits
[i
]^xor_mask
) & kv_bits
[i
]);
734 count
+= count_ones ((v_bits
[i
]^xor_mask
) & kv_bits
[i
] & last_mask
);
739 for (i
= 0; i
< kv_len
; i
++)
740 if (scm_is_true (scm_array_handle_ref (&kv_handle
, i
)))
742 SCM elt
= scm_array_handle_ref (&v_handle
, i
*v_inc
);
743 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
748 scm_array_handle_release (&kv_handle
);
751 else if (scm_is_true (scm_u32vector_p (kv
)))
753 scm_t_array_handle kv_handle
;
756 const scm_t_uint32
*kv_elts
;
758 kv_elts
= scm_u32vector_elements (kv
, &kv_handle
, &kv_len
, &kv_inc
);
759 for (i
= 0; i
< kv_len
; i
++, kv_elts
+= kv_inc
)
761 SCM elt
= scm_array_handle_ref (&v_handle
, (*kv_elts
)*v_inc
);
762 if ((bit
&& scm_is_true (elt
)) || (!bit
&& scm_is_false (elt
)))
766 scm_array_handle_release (&kv_handle
);
769 scm_wrong_type_arg_msg (NULL
, 0, kv
, "bitvector or u32vector");
771 scm_array_handle_release (&v_handle
);
773 return scm_from_size_t (count
);
777 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
779 "Modify the bit vector @var{v} by replacing each element with\n"
781 #define FUNC_NAME s_scm_bit_invert_x
783 scm_t_array_handle handle
;
788 bits
= scm_bitvector_writable_elements (v
, &handle
, &off
, &len
, &inc
);
790 if (off
== 0 && inc
== 1 && len
> 0)
792 size_t word_len
= (len
+ 31) / 32;
793 scm_t_uint32 last_mask
= ((scm_t_uint32
)-1) >> (32*word_len
- len
);
796 for (i
= 0; i
< word_len
-1; i
++)
798 bits
[i
] = bits
[i
] ^ last_mask
;
803 for (i
= 0; i
< len
; i
++)
804 scm_array_handle_set (&handle
, i
*inc
,
805 scm_not (scm_array_handle_ref (&handle
, i
*inc
)));
808 scm_array_handle_release (&handle
);
810 return SCM_UNSPECIFIED
;
816 scm_istr2bve (SCM str
)
818 scm_t_array_handle handle
;
819 size_t len
= scm_i_string_length (str
);
820 SCM vec
= scm_c_make_bitvector (len
, SCM_UNDEFINED
);
828 data
= scm_bitvector_writable_elements (vec
, &handle
, NULL
, NULL
, NULL
);
829 c_str
= scm_i_string_chars (str
);
831 for (k
= 0; k
< (len
+ 31) / 32; k
++)
837 for (mask
= 1L; j
--; mask
<<= 1)
852 scm_array_handle_release (&handle
);
853 scm_remember_upto_here_1 (str
);
857 /* FIXME: h->array should be h->vector */
859 bitvector_handle_ref (scm_t_array_handle
*h
, size_t pos
)
861 return scm_c_bitvector_ref (h
->array
, pos
);
865 bitvector_handle_set (scm_t_array_handle
*h
, size_t pos
, SCM val
)
867 scm_c_bitvector_set_x (h
->array
, pos
, val
);
871 bitvector_get_handle (SCM bv
, scm_t_array_handle
*h
)
877 h
->dim0
.ubnd
= BITVECTOR_LENGTH (bv
) - 1;
879 h
->element_type
= SCM_ARRAY_ELEMENT_TYPE_BIT
;
880 h
->elements
= h
->writable_elements
= BITVECTOR_BITS (bv
);
883 SCM_ARRAY_IMPLEMENTATION (SCM_SMOB_TYPE_BITS (scm_tc16_bitvector
),
885 bitvector_handle_ref
, bitvector_handle_set
,
886 bitvector_get_handle
)
887 SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_BIT
, scm_make_bitvector
)
890 scm_init_bitvectors ()
892 scm_tc16_bitvector
= scm_make_smob_type ("bitvector", 0);
893 scm_set_smob_print (scm_tc16_bitvector
, bitvector_print
);
894 scm_set_smob_equalp (scm_tc16_bitvector
, bitvector_equalp
);
896 #include "libguile/bitvectors.x"