summaryrefslogtreecommitdiff
path: root/libguile/array-handle.h
blob: caf9cefbfd7344a858200b81bf97998a40634660 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* classes: h_files */

#ifndef SCM_ARRAY_HANDLE_H
#define SCM_ARRAY_HANDLE_H

/* Copyright (C) 1995,1996,1997,1999,2000,2001, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */



#include "libguile/__scm.h"



struct scm_t_array_handle;

typedef SCM (*scm_i_t_array_ref) (struct scm_t_array_handle *, size_t);
typedef void (*scm_i_t_array_set) (struct scm_t_array_handle *, size_t, SCM);

typedef struct
{
  scm_t_bits tag;
  scm_t_bits mask;
  scm_i_t_array_ref vref;
  scm_i_t_array_set vset;
  void (*get_handle)(SCM, struct scm_t_array_handle*);
} scm_t_array_implementation;
  
#define SCM_ARRAY_IMPLEMENTATION(tag_,mask_,vref_,vset_,handle_) \
  SCM_SNARF_INIT ({                                                     \
      scm_t_array_implementation impl;                                  \
      impl.tag = tag_; impl.mask = mask_;                               \
      impl.vref = vref_; impl.vset = vset_;                             \
      impl.get_handle = handle_;                                        \
      scm_i_register_array_implementation (&impl);                      \
  })
  

SCM_INTERNAL void scm_i_register_array_implementation (scm_t_array_implementation *impl);
SCM_INTERNAL scm_t_array_implementation* scm_i_array_implementation_for_obj (SCM obj);




typedef struct scm_t_array_dim
{
  ssize_t lbnd;
  ssize_t ubnd;
  ssize_t inc;
} scm_t_array_dim;

typedef enum {    
  SCM_ARRAY_ELEMENT_TYPE_SCM = 0, /* SCM values */
  SCM_ARRAY_ELEMENT_TYPE_CHAR = 1, /* characters */
  SCM_ARRAY_ELEMENT_TYPE_BIT = 2, /* packed numeric values */
  SCM_ARRAY_ELEMENT_TYPE_VU8 = 3,
  SCM_ARRAY_ELEMENT_TYPE_U8 = 4,
  SCM_ARRAY_ELEMENT_TYPE_S8 = 5,
  SCM_ARRAY_ELEMENT_TYPE_U16 = 6,
  SCM_ARRAY_ELEMENT_TYPE_S16 = 7,
  SCM_ARRAY_ELEMENT_TYPE_U32 = 8,
  SCM_ARRAY_ELEMENT_TYPE_S32 = 9,
  SCM_ARRAY_ELEMENT_TYPE_U64 = 10,
  SCM_ARRAY_ELEMENT_TYPE_S64 = 11,
  SCM_ARRAY_ELEMENT_TYPE_F32 = 12,
  SCM_ARRAY_ELEMENT_TYPE_F64 = 13,
  SCM_ARRAY_ELEMENT_TYPE_C32 = 14,
  SCM_ARRAY_ELEMENT_TYPE_C64 = 15,
  SCM_ARRAY_ELEMENT_TYPE_LAST = 15,
} scm_t_array_element_type;

SCM_INTERNAL SCM scm_i_array_element_types[];


typedef struct scm_t_array_handle {
  SCM array;
  scm_t_array_implementation *impl;
  /* `Base' is an offset into elements or writable_elements, corresponding to
     the first element in the array. It would be nicer just to adjust the
     elements/writable_elements pointer, but we can't because that element might
     not even be byte-addressable, as is the case with bitvectors. A nicer
     solution would be, well, nice.
   */
  size_t base;
  size_t ndims; /* ndims == the rank of the array */
  scm_t_array_dim *dims;
  scm_t_array_dim dim0;
  scm_t_array_element_type element_type;
  const void *elements;
  void *writable_elements;
} scm_t_array_handle;

#define scm_array_handle_rank(h) ((h)->ndims)
#define scm_array_handle_dims(h) ((h)->dims)

SCM_API void scm_array_get_handle (SCM array, scm_t_array_handle *h);
SCM_API ssize_t scm_array_handle_pos (scm_t_array_handle *h, SCM indices);
SCM_API SCM scm_array_handle_element_type (scm_t_array_handle *h);
SCM_API void scm_array_handle_release (scm_t_array_handle *h);
SCM_API const SCM* scm_array_handle_elements (scm_t_array_handle *h);
SCM_API SCM* scm_array_handle_writable_elements (scm_t_array_handle *h);

/* See inline.h for scm_array_handle_ref and scm_array_handle_set */

SCM_INTERNAL void scm_init_array_handle (void);


#endif  /* SCM_ARRAY_HANDLE_H */

/*
  Local Variables:
  c-file-style: "gnu"
  End:
*/