srfi-4.i.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* This file defines the procedures related to one type of uniform
  2. numeric vector. It is included multiple time in srfi-4.c, once for
  3. each type.
  4. Before inclusion, the following macros must be defined. They are
  5. undefined at the end of this file to get back to a clean slate for
  6. the next inclusion.
  7. - TYPE
  8. The type tag of the vector, for example SCM_UVEC_U8
  9. - TAG
  10. The tag name of the vector, for example u8. The tag is used to
  11. form the function names and is included in the docstrings, for
  12. example.
  13. - CTYPE
  14. The C type of the elements, for example scm_t_uint8. The code
  15. below will never do sizeof (CTYPE), thus you can use just 'float'
  16. for the c32 type, for example.
  17. When CTYPE is not defined, the functions using it are excluded.
  18. */
  19. /* The first level does not expand macros in the arguments. */
  20. #define paste(a1,a2,a3) a1##a2##a3
  21. #define s_paste(a1,a2,a3) s_##a1##a2##a3
  22. #define stringify(a) #a
  23. /* But the second level does. */
  24. #define F(pre,T,suf) paste(pre,T,suf)
  25. #define s_F(pre,T,suf) s_paste(pre,T,suf)
  26. #define S(T) stringify(T)
  27. SCM_DEFINE (F(scm_,TAG,vector_p), S(TAG)"vector?", 1, 0, 0,
  28. (SCM obj),
  29. "Return @code{#t} if @var{obj} is a vector of type " S(TAG) ",\n"
  30. "@code{#f} otherwise.")
  31. #define FUNC_NAME s_F(scm_, TAG, vector_p)
  32. {
  33. return uvec_p (TYPE, obj);
  34. }
  35. #undef FUNC_NAME
  36. SCM_DEFINE (F(scm_make_,TAG,vector), "make-"S(TAG)"vector", 1, 1, 0,
  37. (SCM len, SCM fill),
  38. "Return a newly allocated uniform numeric vector which can\n"
  39. "hold @var{len} elements. If @var{fill} is given, it is used to\n"
  40. "initialize the elements, otherwise the contents of the vector\n"
  41. "is unspecified.")
  42. #define FUNC_NAME s_S(scm_make_,TAG,vector)
  43. {
  44. return make_uvec (TYPE, len, fill);
  45. }
  46. #undef FUNC_NAME
  47. SCM_DEFINE (F(scm_,TAG,vector), S(TAG)"vector", 0, 0, 1,
  48. (SCM l),
  49. "Return a newly allocated uniform numeric vector containing\n"
  50. "all argument values.")
  51. #define FUNC_NAME s_F(scm_,TAG,vector)
  52. {
  53. return list_to_uvec (TYPE, l);
  54. }
  55. #undef FUNC_NAME
  56. SCM_DEFINE (F(scm_,TAG,vector_length), S(TAG)"vector-length", 1, 0, 0,
  57. (SCM uvec),
  58. "Return the number of elements in the uniform numeric vector\n"
  59. "@var{uvec}.")
  60. #define FUNC_NAME s_F(scm_,TAG,vector_length)
  61. {
  62. return uvec_length (TYPE, uvec);
  63. }
  64. #undef FUNC_NAME
  65. SCM_DEFINE (F(scm_,TAG,vector_ref), S(TAG)"vector-ref", 2, 0, 0,
  66. (SCM uvec, SCM index),
  67. "Return the element at @var{index} in the uniform numeric\n"
  68. "vector @var{uvec}.")
  69. #define FUNC_NAME s_F(scm_,TAG,vector_ref)
  70. {
  71. return uvec_ref (TYPE, uvec, index);
  72. }
  73. #undef FUNC_NAME
  74. SCM_DEFINE (F(scm_,TAG,vector_set_x), S(TAG)"vector-set!", 3, 0, 0,
  75. (SCM uvec, SCM index, SCM value),
  76. "Set the element at @var{index} in the uniform numeric\n"
  77. "vector @var{uvec} to @var{value}. The return value is not\n"
  78. "specified.")
  79. #define FUNC_NAME s_F(scm_,TAG,vector_set_x)
  80. {
  81. return uvec_set_x (TYPE, uvec, index, value);
  82. }
  83. #undef FUNC_NAME
  84. SCM_DEFINE (F(scm_,TAG,vector_to_list), S(TAG)"vector->list", 1, 0, 0,
  85. (SCM uvec),
  86. "Convert the uniform numeric vector @var{uvec} to a list.")
  87. #define FUNC_NAME s_F(scm_,TAG,vector_to_list)
  88. {
  89. return uvec_to_list (TYPE, uvec);
  90. }
  91. #undef FUNC_NAME
  92. SCM_DEFINE (F(scm_list_to_,TAG,vector), "list->"S(TAG)"vector", 1, 0, 0,
  93. (SCM l),
  94. "Convert the list @var{l} to a numeric uniform vector.")
  95. #define FUNC_NAME s_F(scm_list_to_,TAG,vector)
  96. {
  97. return list_to_uvec (TYPE, l);
  98. }
  99. #undef FUNC_NAME
  100. SCM_DEFINE (F(scm_any_to_,TAG,vector), "any->"S(TAG)"vector", 1, 0, 0,
  101. (SCM obj),
  102. "Convert @var{obj}, which can be a list, vector, or\n"
  103. "uniform vector, to a numeric uniform vector of\n"
  104. "type " S(TAG)".")
  105. #define FUNC_NAME s_F(scm_any_to_,TAG,vector)
  106. {
  107. return coerce_to_uvec (TYPE, obj);
  108. }
  109. #undef FUNC_NAME
  110. #ifdef CTYPE
  111. SCM
  112. F(scm_take_,TAG,vector) (CTYPE *data, size_t n)
  113. {
  114. scm_gc_register_collectable_memory ((void *)data, n*uvec_sizes[TYPE],
  115. uvec_names[TYPE]);
  116. return take_uvec (TYPE, data, n);
  117. }
  118. const CTYPE *
  119. F(scm_array_handle_,TAG,_elements) (scm_t_array_handle *h)
  120. {
  121. return F(scm_array_handle_,TAG,_writable_elements) (h);
  122. }
  123. CTYPE *
  124. F(scm_array_handle_,TAG,_writable_elements) (scm_t_array_handle *h)
  125. {
  126. SCM vec = h->array;
  127. if (SCM_I_ARRAYP (vec))
  128. vec = SCM_I_ARRAY_V (vec);
  129. uvec_assert (TYPE, vec);
  130. if (TYPE == SCM_UVEC_C32 || TYPE == SCM_UVEC_C64)
  131. return ((CTYPE *)SCM_UVEC_BASE (vec)) + 2*h->base;
  132. else
  133. return ((CTYPE *)SCM_UVEC_BASE (vec)) + h->base;
  134. }
  135. const CTYPE *
  136. F(scm_,TAG,vector_elements) (SCM uvec,
  137. scm_t_array_handle *h,
  138. size_t *lenp, ssize_t *incp)
  139. {
  140. return F(scm_,TAG,vector_writable_elements) (uvec, h, lenp, incp);
  141. }
  142. CTYPE *
  143. F(scm_,TAG,vector_writable_elements) (SCM uvec,
  144. scm_t_array_handle *h,
  145. size_t *lenp, ssize_t *incp)
  146. {
  147. scm_generalized_vector_get_handle (uvec, h);
  148. if (lenp)
  149. {
  150. scm_t_array_dim *dim = scm_array_handle_dims (h);
  151. *lenp = dim->ubnd - dim->lbnd + 1;
  152. *incp = dim->inc;
  153. }
  154. return F(scm_array_handle_,TAG,_writable_elements) (h);
  155. }
  156. #endif
  157. static SCM
  158. F(,TAG,ref) (scm_t_array_handle *handle, ssize_t pos)
  159. {
  160. return uvec_fast_ref (TYPE, handle->elements, pos);
  161. }
  162. static void
  163. F(,TAG,set) (scm_t_array_handle *handle, ssize_t pos, SCM val)
  164. {
  165. uvec_fast_set_x (TYPE, handle->writable_elements, pos, val);
  166. }
  167. #undef paste
  168. #undef s_paste
  169. #undef stringify
  170. #undef F
  171. #undef s_F
  172. #undef S
  173. #undef TYPE
  174. #undef TAG
  175. #undef CTYPE