array-handle.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009, 2011 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 License
  5. * as published by the Free Software Foundation; either version 3 of
  6. * the License, or (at your option) any later version.
  7. *
  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.
  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
  16. * 02110-1301 USA
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21. #include "libguile/_scm.h"
  22. #include "libguile/__scm.h"
  23. #include "libguile/array-handle.h"
  24. SCM scm_i_array_element_types[SCM_ARRAY_ELEMENT_TYPE_LAST + 1];
  25. #define ARRAY_IMPLS_N_STATIC_ALLOC 7
  26. static scm_t_array_implementation array_impls[ARRAY_IMPLS_N_STATIC_ALLOC];
  27. static int num_array_impls_registered = 0;
  28. void
  29. scm_i_register_array_implementation (scm_t_array_implementation *impl)
  30. {
  31. if (num_array_impls_registered >= ARRAY_IMPLS_N_STATIC_ALLOC)
  32. /* need to increase ARRAY_IMPLS_N_STATIC_ALLOC, buster */
  33. abort ();
  34. else
  35. array_impls[num_array_impls_registered++] = *impl;
  36. }
  37. scm_t_array_implementation*
  38. scm_i_array_implementation_for_obj (SCM obj)
  39. {
  40. int i;
  41. for (i = 0; i < num_array_impls_registered; i++)
  42. if (SCM_NIMP (obj)
  43. && (SCM_CELL_TYPE (obj) & array_impls[i].mask) == array_impls[i].tag)
  44. return &array_impls[i];
  45. return NULL;
  46. }
  47. void
  48. scm_array_get_handle (SCM array, scm_t_array_handle *h)
  49. {
  50. scm_t_array_implementation *impl = scm_i_array_implementation_for_obj (array);
  51. if (!impl)
  52. scm_wrong_type_arg_msg (NULL, 0, array, "array");
  53. h->array = array;
  54. h->impl = impl;
  55. h->base = 0;
  56. h->ndims = 0;
  57. h->dims = NULL;
  58. h->element_type = SCM_ARRAY_ELEMENT_TYPE_SCM; /* have to default to
  59. something... */
  60. h->elements = NULL;
  61. h->writable_elements = NULL;
  62. h->impl->get_handle (array, h);
  63. }
  64. ssize_t
  65. scm_array_handle_pos (scm_t_array_handle *h, SCM indices)
  66. {
  67. scm_t_array_dim *s = scm_array_handle_dims (h);
  68. ssize_t pos = 0, i;
  69. size_t k = scm_array_handle_rank (h);
  70. while (k > 0 && scm_is_pair (indices))
  71. {
  72. i = scm_to_signed_integer (SCM_CAR (indices), s->lbnd, s->ubnd);
  73. pos += (i - s->lbnd) * s->inc;
  74. k--;
  75. s++;
  76. indices = SCM_CDR (indices);
  77. }
  78. if (k > 0 || !scm_is_null (indices))
  79. scm_misc_error (NULL, "wrong number of indices, expecting ~a",
  80. scm_list_1 (scm_from_size_t (scm_array_handle_rank (h))));
  81. return pos;
  82. }
  83. SCM
  84. scm_array_handle_element_type (scm_t_array_handle *h)
  85. {
  86. if (h->element_type < 0 || h->element_type > SCM_ARRAY_ELEMENT_TYPE_LAST)
  87. abort (); /* guile programming error */
  88. return scm_i_array_element_types[h->element_type];
  89. }
  90. void
  91. scm_array_handle_release (scm_t_array_handle *h)
  92. {
  93. /* Nothing to do here until arrays need to be reserved for real.
  94. */
  95. }
  96. const SCM *
  97. scm_array_handle_elements (scm_t_array_handle *h)
  98. {
  99. if (h->element_type != SCM_ARRAY_ELEMENT_TYPE_SCM)
  100. scm_wrong_type_arg_msg (NULL, 0, h->array, "non-uniform array");
  101. return ((const SCM*)h->elements) + h->base;
  102. }
  103. SCM *
  104. scm_array_handle_writable_elements (scm_t_array_handle *h)
  105. {
  106. if (h->element_type != SCM_ARRAY_ELEMENT_TYPE_SCM)
  107. scm_wrong_type_arg_msg (NULL, 0, h->array, "non-uniform array");
  108. return ((SCM*)h->elements) + h->base;
  109. }
  110. void
  111. scm_init_array_handle (void)
  112. {
  113. #define DEFINE_ARRAY_TYPE(tag, TAG) \
  114. scm_i_array_element_types[SCM_ARRAY_ELEMENT_TYPE_##TAG] = scm_from_utf8_symbol (#tag)
  115. scm_i_array_element_types[SCM_ARRAY_ELEMENT_TYPE_SCM] = SCM_BOOL_T;
  116. DEFINE_ARRAY_TYPE (a, CHAR);
  117. DEFINE_ARRAY_TYPE (b, BIT);
  118. DEFINE_ARRAY_TYPE (vu8, VU8);
  119. DEFINE_ARRAY_TYPE (u8, U8);
  120. DEFINE_ARRAY_TYPE (s8, S8);
  121. DEFINE_ARRAY_TYPE (u16, U16);
  122. DEFINE_ARRAY_TYPE (s16, S16);
  123. DEFINE_ARRAY_TYPE (u32, U32);
  124. DEFINE_ARRAY_TYPE (s32, S32);
  125. DEFINE_ARRAY_TYPE (u64, U64);
  126. DEFINE_ARRAY_TYPE (s64, S64);
  127. DEFINE_ARRAY_TYPE (f32, F32);
  128. DEFINE_ARRAY_TYPE (f64, F64);
  129. DEFINE_ARRAY_TYPE (c32, C32);
  130. DEFINE_ARRAY_TYPE (c64, C64);
  131. #include "libguile/array-handle.x"
  132. }
  133. /*
  134. Local Variables:
  135. c-file-style: "gnu"
  136. End:
  137. */