vectors.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but 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.
  12. *
  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 02110-1301 USA
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include "libguile/_scm.h"
  21. #include "libguile/eq.h"
  22. #include "libguile/root.h"
  23. #include "libguile/strings.h"
  24. #include "libguile/lang.h"
  25. #include "libguile/validate.h"
  26. #include "libguile/vectors.h"
  27. #include "libguile/unif.h"
  28. #include "libguile/ramap.h"
  29. #include "libguile/srfi-4.h"
  30. #include "libguile/strings.h"
  31. #include "libguile/srfi-13.h"
  32. #include "libguile/dynwind.h"
  33. #include "libguile/deprecation.h"
  34. #define VECTOR_MAX_LENGTH (SCM_T_BITS_MAX >> 8)
  35. int
  36. scm_is_vector (SCM obj)
  37. {
  38. if (SCM_I_IS_VECTOR (obj))
  39. return 1;
  40. if (SCM_I_ARRAYP (obj) && SCM_I_ARRAY_NDIM (obj) == 1)
  41. {
  42. SCM v = SCM_I_ARRAY_V (obj);
  43. return SCM_I_IS_VECTOR (v);
  44. }
  45. return 0;
  46. }
  47. int
  48. scm_is_simple_vector (SCM obj)
  49. {
  50. return SCM_I_IS_VECTOR (obj);
  51. }
  52. const SCM *
  53. scm_vector_elements (SCM vec, scm_t_array_handle *h,
  54. size_t *lenp, ssize_t *incp)
  55. {
  56. scm_generalized_vector_get_handle (vec, h);
  57. if (lenp)
  58. {
  59. scm_t_array_dim *dim = scm_array_handle_dims (h);
  60. *lenp = dim->ubnd - dim->lbnd + 1;
  61. *incp = dim->inc;
  62. }
  63. return scm_array_handle_elements (h);
  64. }
  65. SCM *
  66. scm_vector_writable_elements (SCM vec, scm_t_array_handle *h,
  67. size_t *lenp, ssize_t *incp)
  68. {
  69. scm_generalized_vector_get_handle (vec, h);
  70. if (lenp)
  71. {
  72. scm_t_array_dim *dim = scm_array_handle_dims (h);
  73. *lenp = dim->ubnd - dim->lbnd + 1;
  74. *incp = dim->inc;
  75. }
  76. return scm_array_handle_writable_elements (h);
  77. }
  78. SCM_DEFINE (scm_vector_p, "vector?", 1, 0, 0,
  79. (SCM obj),
  80. "Return @code{#t} if @var{obj} is a vector, otherwise return\n"
  81. "@code{#f}.")
  82. #define FUNC_NAME s_scm_vector_p
  83. {
  84. return scm_from_bool (scm_is_vector (obj));
  85. }
  86. #undef FUNC_NAME
  87. SCM_GPROC (s_vector_length, "vector-length", 1, 0, 0, scm_vector_length, g_vector_length);
  88. /* Returns the number of elements in @var{vector} as an exact integer. */
  89. SCM
  90. scm_vector_length (SCM v)
  91. {
  92. if (SCM_I_IS_VECTOR (v))
  93. return scm_from_size_t (SCM_I_VECTOR_LENGTH (v));
  94. else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
  95. {
  96. scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
  97. return scm_from_size_t (dim->ubnd - dim->lbnd + 1);
  98. }
  99. else
  100. SCM_WTA_DISPATCH_1 (g_vector_length, v, 1, NULL);
  101. }
  102. size_t
  103. scm_c_vector_length (SCM v)
  104. {
  105. if (SCM_I_IS_VECTOR (v))
  106. return SCM_I_VECTOR_LENGTH (v);
  107. else
  108. return scm_to_size_t (scm_vector_length (v));
  109. }
  110. SCM_REGISTER_PROC (s_list_to_vector, "list->vector", 1, 0, 0, scm_vector);
  111. /*
  112. "Return a newly created vector initialized to the elements of"
  113. "the list @var{list}.\n\n"
  114. "@lisp\n"
  115. "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
  116. "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
  117. "@end lisp")
  118. */
  119. SCM_DEFINE (scm_vector, "vector", 0, 0, 1,
  120. (SCM l),
  121. "@deffnx {Scheme Procedure} list->vector l\n"
  122. "Return a newly allocated vector composed of the\n"
  123. "given arguments. Analogous to @code{list}.\n"
  124. "\n"
  125. "@lisp\n"
  126. "(vector 'a 'b 'c) @result{} #(a b c)\n"
  127. "@end lisp")
  128. #define FUNC_NAME s_scm_vector
  129. {
  130. SCM res;
  131. SCM *data;
  132. long i, len;
  133. scm_t_array_handle handle;
  134. SCM_VALIDATE_LIST_COPYLEN (1, l, len);
  135. res = scm_c_make_vector (len, SCM_UNSPECIFIED);
  136. data = scm_vector_writable_elements (res, &handle, NULL, NULL);
  137. i = 0;
  138. while (scm_is_pair (l) && i < len)
  139. {
  140. data[i] = SCM_CAR (l);
  141. l = SCM_CDR (l);
  142. i += 1;
  143. }
  144. scm_array_handle_release (&handle);
  145. return res;
  146. }
  147. #undef FUNC_NAME
  148. SCM_GPROC (s_vector_ref, "vector-ref", 2, 0, 0, scm_vector_ref, g_vector_ref);
  149. /*
  150. "@var{k} must be a valid index of @var{vector}.\n"
  151. "@samp{Vector-ref} returns the contents of element @var{k} of\n"
  152. "@var{vector}.\n\n"
  153. "@lisp\n"
  154. "(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8\n"
  155. "(vector-ref '#(1 1 2 3 5 8 13 21)\n"
  156. " (let ((i (round (* 2 (acos -1)))))\n"
  157. " (if (inexact? i)\n"
  158. " (inexact->exact i)\n"
  159. " i))) @result{} 13\n"
  160. "@end lisp"
  161. */
  162. SCM
  163. scm_vector_ref (SCM v, SCM k)
  164. #define FUNC_NAME s_vector_ref
  165. {
  166. return scm_c_vector_ref (v, scm_to_size_t (k));
  167. }
  168. #undef FUNC_NAME
  169. SCM
  170. scm_c_vector_ref (SCM v, size_t k)
  171. {
  172. if (SCM_I_IS_VECTOR (v))
  173. {
  174. if (k >= SCM_I_VECTOR_LENGTH (v))
  175. scm_out_of_range (NULL, scm_from_size_t (k));
  176. return (SCM_I_VECTOR_ELTS(v))[k];
  177. }
  178. else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
  179. {
  180. scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
  181. SCM vv = SCM_I_ARRAY_V (v);
  182. if (SCM_I_IS_VECTOR (vv))
  183. {
  184. if (k >= dim->ubnd - dim->lbnd + 1)
  185. scm_out_of_range (NULL, scm_from_size_t (k));
  186. k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
  187. return (SCM_I_VECTOR_ELTS (vv))[k];
  188. }
  189. scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
  190. }
  191. else
  192. SCM_WTA_DISPATCH_2 (g_vector_ref, v, scm_from_size_t (k), 2, NULL);
  193. }
  194. SCM_GPROC (s_vector_set_x, "vector-set!", 3, 0, 0, scm_vector_set_x, g_vector_set_x);
  195. /* "@var{k} must be a valid index of @var{vector}.\n"
  196. "@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}.\n"
  197. "The value returned by @samp{vector-set!} is unspecified.\n"
  198. "@lisp\n"
  199. "(let ((vec (vector 0 '(2 2 2 2) "Anna")))\n"
  200. " (vector-set! vec 1 '("Sue" "Sue"))\n"
  201. " vec) @result{} #(0 ("Sue" "Sue") "Anna")\n"
  202. "(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector\n"
  203. "@end lisp"
  204. */
  205. SCM
  206. scm_vector_set_x (SCM v, SCM k, SCM obj)
  207. #define FUNC_NAME s_vector_set_x
  208. {
  209. scm_c_vector_set_x (v, scm_to_size_t (k), obj);
  210. return SCM_UNSPECIFIED;
  211. }
  212. #undef FUNC_NAME
  213. void
  214. scm_c_vector_set_x (SCM v, size_t k, SCM obj)
  215. {
  216. if (SCM_I_IS_VECTOR (v))
  217. {
  218. if (k >= SCM_I_VECTOR_LENGTH (v))
  219. scm_out_of_range (NULL, scm_from_size_t (k));
  220. (SCM_I_VECTOR_WELTS(v))[k] = obj;
  221. }
  222. else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
  223. {
  224. scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
  225. SCM vv = SCM_I_ARRAY_V (v);
  226. if (SCM_I_IS_VECTOR (vv))
  227. {
  228. if (k >= dim->ubnd - dim->lbnd + 1)
  229. scm_out_of_range (NULL, scm_from_size_t (k));
  230. k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
  231. (SCM_I_VECTOR_WELTS (vv))[k] = obj;
  232. }
  233. else
  234. scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
  235. }
  236. else
  237. {
  238. if (SCM_UNPACK (g_vector_set_x))
  239. scm_apply_generic (g_vector_set_x,
  240. scm_list_3 (v, scm_from_size_t (k), obj));
  241. else
  242. scm_wrong_type_arg_msg (NULL, 0, v, "vector");
  243. }
  244. }
  245. SCM_DEFINE (scm_make_vector, "make-vector", 1, 1, 0,
  246. (SCM k, SCM fill),
  247. "Return a newly allocated vector of @var{k} elements. If a\n"
  248. "second argument is given, then each position is initialized to\n"
  249. "@var{fill}. Otherwise the initial contents of each position is\n"
  250. "unspecified.")
  251. #define FUNC_NAME s_scm_make_vector
  252. {
  253. size_t l = scm_to_unsigned_integer (k, 0, VECTOR_MAX_LENGTH);
  254. if (SCM_UNBNDP (fill))
  255. fill = SCM_UNSPECIFIED;
  256. return scm_c_make_vector (l, fill);
  257. }
  258. #undef FUNC_NAME
  259. SCM
  260. scm_c_make_vector (size_t k, SCM fill)
  261. #define FUNC_NAME s_scm_make_vector
  262. {
  263. SCM v;
  264. SCM *base;
  265. if (k > 0)
  266. {
  267. unsigned long int j;
  268. SCM_ASSERT_RANGE (1, scm_from_ulong (k), k <= VECTOR_MAX_LENGTH);
  269. base = scm_gc_malloc (k * sizeof (SCM), "vector");
  270. for (j = 0; j != k; ++j)
  271. base[j] = fill;
  272. }
  273. else
  274. base = NULL;
  275. v = scm_cell ((k << 8) | scm_tc7_vector, (scm_t_bits) base);
  276. scm_remember_upto_here_1 (fill);
  277. return v;
  278. }
  279. #undef FUNC_NAME
  280. SCM_DEFINE (scm_vector_copy, "vector-copy", 1, 0, 0,
  281. (SCM vec),
  282. "Return a copy of @var{vec}.")
  283. #define FUNC_NAME s_scm_vector_copy
  284. {
  285. scm_t_array_handle handle;
  286. size_t i, len;
  287. ssize_t inc;
  288. const SCM *src;
  289. SCM *dst;
  290. src = scm_vector_elements (vec, &handle, &len, &inc);
  291. dst = scm_gc_malloc (len * sizeof (SCM), "vector");
  292. for (i = 0; i < len; i++, src += inc)
  293. dst[i] = *src;
  294. scm_array_handle_release (&handle);
  295. return scm_cell ((len << 8) | scm_tc7_vector, (scm_t_bits) dst);
  296. }
  297. #undef FUNC_NAME
  298. void
  299. scm_i_vector_free (SCM vec)
  300. {
  301. scm_gc_free (SCM_I_VECTOR_WELTS (vec),
  302. SCM_I_VECTOR_LENGTH (vec) * sizeof(SCM),
  303. "vector");
  304. }
  305. /* Allocate memory for a weak vector on behalf of the caller. The allocated
  306. * vector will be of the given weak vector subtype. It will contain size
  307. * elements which are initialized with the 'fill' object, or, if 'fill' is
  308. * undefined, with an unspecified object.
  309. */
  310. SCM
  311. scm_i_allocate_weak_vector (scm_t_bits type, SCM size, SCM fill)
  312. {
  313. size_t c_size;
  314. SCM *base;
  315. SCM v;
  316. c_size = scm_to_unsigned_integer (size, 0, VECTOR_MAX_LENGTH);
  317. if (c_size > 0)
  318. {
  319. size_t j;
  320. if (SCM_UNBNDP (fill))
  321. fill = SCM_UNSPECIFIED;
  322. base = scm_gc_malloc (c_size * sizeof (SCM), "weak vector");
  323. for (j = 0; j != c_size; ++j)
  324. base[j] = fill;
  325. }
  326. else
  327. base = NULL;
  328. v = scm_double_cell ((c_size << 8) | scm_tc7_wvect,
  329. (scm_t_bits) base,
  330. type,
  331. SCM_UNPACK (SCM_EOL));
  332. scm_remember_upto_here_1 (fill);
  333. return v;
  334. }
  335. SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
  336. (SCM v),
  337. "Return a newly allocated list composed of the elements of @var{v}.\n"
  338. "\n"
  339. "@lisp\n"
  340. "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
  341. "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
  342. "@end lisp")
  343. #define FUNC_NAME s_scm_vector_to_list
  344. {
  345. SCM res = SCM_EOL;
  346. const SCM *data;
  347. scm_t_array_handle handle;
  348. size_t i, count, len;
  349. ssize_t inc;
  350. data = scm_vector_elements (v, &handle, &len, &inc);
  351. for (i = (len - 1) * inc, count = 0;
  352. count < len;
  353. i -= inc, count++)
  354. res = scm_cons (data[i], res);
  355. scm_array_handle_release (&handle);
  356. return res;
  357. }
  358. #undef FUNC_NAME
  359. SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
  360. (SCM v, SCM fill),
  361. "Store @var{fill} in every position of @var{vector}. The value\n"
  362. "returned by @code{vector-fill!} is unspecified.")
  363. #define FUNC_NAME s_scm_vector_fill_x
  364. {
  365. scm_t_array_handle handle;
  366. SCM *data;
  367. size_t i, len;
  368. ssize_t inc;
  369. data = scm_vector_writable_elements (v, &handle, &len, &inc);
  370. for (i = 0; i < len; i += inc)
  371. data[i] = fill;
  372. scm_array_handle_release (&handle);
  373. return SCM_UNSPECIFIED;
  374. }
  375. #undef FUNC_NAME
  376. SCM
  377. scm_i_vector_equal_p (SCM x, SCM y)
  378. {
  379. long i;
  380. for (i = SCM_I_VECTOR_LENGTH (x) - 1; i >= 0; i--)
  381. if (scm_is_false (scm_equal_p (SCM_I_VECTOR_ELTS (x)[i],
  382. SCM_I_VECTOR_ELTS (y)[i])))
  383. return SCM_BOOL_F;
  384. return SCM_BOOL_T;
  385. }
  386. SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
  387. (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
  388. "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
  389. "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
  390. "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
  391. "@code{vector-move-left!} copies elements in leftmost order.\n"
  392. "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
  393. "same vector, @code{vector-move-left!} is usually appropriate when\n"
  394. "@var{start1} is greater than @var{start2}.")
  395. #define FUNC_NAME s_scm_vector_move_left_x
  396. {
  397. scm_t_array_handle handle1, handle2;
  398. const SCM *elts1;
  399. SCM *elts2;
  400. size_t len1, len2;
  401. ssize_t inc1, inc2;
  402. size_t i, j, e;
  403. elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
  404. elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
  405. i = scm_to_unsigned_integer (start1, 0, len1);
  406. e = scm_to_unsigned_integer (end1, i, len1);
  407. j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
  408. i *= inc1;
  409. e *= inc1;
  410. j *= inc2;
  411. for (; i < e; i += inc1, j += inc2)
  412. elts2[j] = elts1[i];
  413. scm_array_handle_release (&handle2);
  414. scm_array_handle_release (&handle1);
  415. return SCM_UNSPECIFIED;
  416. }
  417. #undef FUNC_NAME
  418. SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
  419. (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
  420. "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
  421. "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
  422. "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
  423. "@code{vector-move-right!} copies elements in rightmost order.\n"
  424. "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
  425. "same vector, @code{vector-move-right!} is usually appropriate when\n"
  426. "@var{start1} is less than @var{start2}.")
  427. #define FUNC_NAME s_scm_vector_move_right_x
  428. {
  429. scm_t_array_handle handle1, handle2;
  430. const SCM *elts1;
  431. SCM *elts2;
  432. size_t len1, len2;
  433. ssize_t inc1, inc2;
  434. size_t i, j, e;
  435. elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
  436. elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
  437. i = scm_to_unsigned_integer (start1, 0, len1);
  438. e = scm_to_unsigned_integer (end1, i, len1);
  439. j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
  440. i *= inc1;
  441. e *= inc1;
  442. j *= inc2;
  443. while (i < e)
  444. {
  445. e -= inc1;
  446. j -= inc2;
  447. elts2[j] = elts1[e];
  448. }
  449. scm_array_handle_release (&handle2);
  450. scm_array_handle_release (&handle1);
  451. return SCM_UNSPECIFIED;
  452. }
  453. #undef FUNC_NAME
  454. /* Generalized vectors. */
  455. int
  456. scm_is_generalized_vector (SCM obj)
  457. {
  458. return (scm_is_vector (obj)
  459. || scm_is_string (obj)
  460. || scm_is_bitvector (obj)
  461. || scm_is_uniform_vector (obj));
  462. }
  463. SCM_DEFINE (scm_generalized_vector_p, "generalized-vector?", 1, 0, 0,
  464. (SCM obj),
  465. "Return @code{#t} if @var{obj} is a vector, string,\n"
  466. "bitvector, or uniform numeric vector.")
  467. #define FUNC_NAME s_scm_generalized_vector_p
  468. {
  469. return scm_from_bool (scm_is_generalized_vector (obj));
  470. }
  471. #undef FUNC_NAME
  472. void
  473. scm_generalized_vector_get_handle (SCM vec, scm_t_array_handle *h)
  474. {
  475. scm_array_get_handle (vec, h);
  476. if (scm_array_handle_rank (h) != 1)
  477. scm_wrong_type_arg_msg (NULL, 0, vec, "vector");
  478. }
  479. size_t
  480. scm_c_generalized_vector_length (SCM v)
  481. {
  482. if (scm_is_vector (v))
  483. return scm_c_vector_length (v);
  484. else if (scm_is_string (v))
  485. return scm_c_string_length (v);
  486. else if (scm_is_bitvector (v))
  487. return scm_c_bitvector_length (v);
  488. else if (scm_is_uniform_vector (v))
  489. return scm_c_uniform_vector_length (v);
  490. else
  491. scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector");
  492. }
  493. SCM_DEFINE (scm_generalized_vector_length, "generalized-vector-length", 1, 0, 0,
  494. (SCM v),
  495. "Return the length of the generalized vector @var{v}.")
  496. #define FUNC_NAME s_scm_generalized_vector_length
  497. {
  498. return scm_from_size_t (scm_c_generalized_vector_length (v));
  499. }
  500. #undef FUNC_NAME
  501. SCM
  502. scm_c_generalized_vector_ref (SCM v, size_t idx)
  503. {
  504. if (scm_is_vector (v))
  505. return scm_c_vector_ref (v, idx);
  506. else if (scm_is_string (v))
  507. return scm_c_string_ref (v, idx);
  508. else if (scm_is_bitvector (v))
  509. return scm_c_bitvector_ref (v, idx);
  510. else if (scm_is_uniform_vector (v))
  511. return scm_c_uniform_vector_ref (v, idx);
  512. else
  513. scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector");
  514. }
  515. SCM_DEFINE (scm_generalized_vector_ref, "generalized-vector-ref", 2, 0, 0,
  516. (SCM v, SCM idx),
  517. "Return the element at index @var{idx} of the\n"
  518. "generalized vector @var{v}.")
  519. #define FUNC_NAME s_scm_generalized_vector_ref
  520. {
  521. return scm_c_generalized_vector_ref (v, scm_to_size_t (idx));
  522. }
  523. #undef FUNC_NAME
  524. void
  525. scm_c_generalized_vector_set_x (SCM v, size_t idx, SCM val)
  526. {
  527. if (scm_is_vector (v))
  528. scm_c_vector_set_x (v, idx, val);
  529. else if (scm_is_string (v))
  530. scm_c_string_set_x (v, idx, val);
  531. else if (scm_is_bitvector (v))
  532. scm_c_bitvector_set_x (v, idx, val);
  533. else if (scm_is_uniform_vector (v))
  534. scm_c_uniform_vector_set_x (v, idx, val);
  535. else
  536. scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector");
  537. }
  538. SCM_DEFINE (scm_generalized_vector_set_x, "generalized-vector-set!", 3, 0, 0,
  539. (SCM v, SCM idx, SCM val),
  540. "Set the element at index @var{idx} of the\n"
  541. "generalized vector @var{v} to @var{val}.")
  542. #define FUNC_NAME s_scm_generalized_vector_set_x
  543. {
  544. scm_c_generalized_vector_set_x (v, scm_to_size_t (idx), val);
  545. return SCM_UNSPECIFIED;
  546. }
  547. #undef FUNC_NAME
  548. SCM_DEFINE (scm_generalized_vector_to_list, "generalized-vector->list", 1, 0, 0,
  549. (SCM v),
  550. "Return a new list whose elements are the elements of the\n"
  551. "generalized vector @var{v}.")
  552. #define FUNC_NAME s_scm_generalized_vector_to_list
  553. {
  554. if (scm_is_vector (v))
  555. return scm_vector_to_list (v);
  556. else if (scm_is_string (v))
  557. return scm_string_to_list (v);
  558. else if (scm_is_bitvector (v))
  559. return scm_bitvector_to_list (v);
  560. else if (scm_is_uniform_vector (v))
  561. return scm_uniform_vector_to_list (v);
  562. else
  563. scm_wrong_type_arg_msg (NULL, 0, v, "generalized vector");
  564. }
  565. #undef FUNC_NAME
  566. void
  567. scm_init_vectors ()
  568. {
  569. scm_nullvect = scm_c_make_vector (0, SCM_UNDEFINED);
  570. #include "libguile/vectors.x"
  571. }
  572. /*
  573. Local Variables:
  574. c-file-style: "gnu"
  575. End:
  576. */