ndtypes 0.2.0dev4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +50 -0
  3. data/Gemfile +2 -0
  4. data/History.md +0 -0
  5. data/README.md +19 -0
  6. data/Rakefile +125 -0
  7. data/ext/ruby_ndtypes/extconf.rb +55 -0
  8. data/ext/ruby_ndtypes/gc_guard.c +36 -0
  9. data/ext/ruby_ndtypes/gc_guard.h +12 -0
  10. data/ext/ruby_ndtypes/ndtypes/AUTHORS.txt +5 -0
  11. data/ext/ruby_ndtypes/ndtypes/INSTALL.txt +101 -0
  12. data/ext/ruby_ndtypes/ndtypes/LICENSE.txt +29 -0
  13. data/ext/ruby_ndtypes/ndtypes/MANIFEST.in +3 -0
  14. data/ext/ruby_ndtypes/ndtypes/Makefile.in +87 -0
  15. data/ext/ruby_ndtypes/ndtypes/README.rst +47 -0
  16. data/ext/ruby_ndtypes/ndtypes/config.guess +1530 -0
  17. data/ext/ruby_ndtypes/ndtypes/config.h.in +67 -0
  18. data/ext/ruby_ndtypes/ndtypes/config.sub +1782 -0
  19. data/ext/ruby_ndtypes/ndtypes/configure +5260 -0
  20. data/ext/ruby_ndtypes/ndtypes/configure.ac +161 -0
  21. data/ext/ruby_ndtypes/ndtypes/doc/Makefile +14 -0
  22. data/ext/ruby_ndtypes/ndtypes/doc/_static/copybutton.js +66 -0
  23. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +26 -0
  24. data/ext/ruby_ndtypes/ndtypes/doc/grammar/grammar.rst +27 -0
  25. data/ext/ruby_ndtypes/ndtypes/doc/index.rst +56 -0
  26. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/context.rst +131 -0
  27. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/encodings.rst +68 -0
  28. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/fields-values.rst +175 -0
  29. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/functions.rst +72 -0
  30. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/index.rst +43 -0
  31. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/init.rst +48 -0
  32. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/io.rst +100 -0
  33. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/memory.rst +124 -0
  34. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/predicates.rst +110 -0
  35. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/typedef.rst +31 -0
  36. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/types.rst +594 -0
  37. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/util.rst +166 -0
  38. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/buffer-protocol.rst +27 -0
  39. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/index.rst +21 -0
  40. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/pattern-matching.rst +330 -0
  41. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/quickstart.rst +144 -0
  42. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +544 -0
  43. data/ext/ruby_ndtypes/ndtypes/doc/releases/index.rst +35 -0
  44. data/ext/ruby_ndtypes/ndtypes/install-sh +527 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +271 -0
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +269 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +230 -0
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.c +268 -0
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.h +109 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.in +73 -0
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.vc +70 -0
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/README.txt +16 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +2179 -0
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +134 -0
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +428 -0
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +2543 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +735 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +176 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +543 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +110 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.c +228 -0
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +634 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.c +116 -0
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +288 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +3067 -0
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +180 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +417 -0
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +1658 -0
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +2773 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +734 -0
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +222 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +1132 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +2323 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +893 -0
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/overflow.h +161 -0
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +473 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +92 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +246 -0
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +269 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +197 -0
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.in +48 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.vc +46 -0
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +1007 -0
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +442 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/slice.h +42 -0
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +238 -0
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +50 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +371 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +100 -0
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +55 -0
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +45 -0
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.c +82 -0
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.h +49 -0
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +1657 -0
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +85 -0
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +115 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +137 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_indent.c +201 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +2397 -0
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_numba.c +57 -0
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +349 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +27839 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +350 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +231 -0
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +375 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typedef.c +65 -0
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/valgrind.supp +30 -0
  108. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/bench.c +79 -0
  109. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/indent.c +94 -0
  110. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/print_ast.c +96 -0
  111. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +474 -0
  112. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +228 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/bench.py +49 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +409 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +14 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +70 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +1332 -0
  118. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/docstrings.h +319 -0
  119. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +154 -0
  120. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +1977 -0
  121. data/ext/ruby_ndtypes/ndtypes/setup.py +288 -0
  122. data/ext/ruby_ndtypes/ndtypes/vcbuild/INSTALL.txt +41 -0
  123. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest32.bat +15 -0
  124. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest64.bat +13 -0
  125. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild32.bat +38 -0
  126. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild64.bat +38 -0
  127. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcclean.bat +13 -0
  128. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcdistclean.bat +14 -0
  129. data/ext/ruby_ndtypes/ruby_ndtypes.c +1003 -0
  130. data/ext/ruby_ndtypes/ruby_ndtypes.h +37 -0
  131. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +28 -0
  132. data/lib/ndtypes.rb +45 -0
  133. data/lib/ndtypes/errors.rb +2 -0
  134. data/lib/ndtypes/version.rb +6 -0
  135. data/ndtypes.gemspec +47 -0
  136. data/spec/gc_table_spec.rb +10 -0
  137. data/spec/ndtypes_spec.rb +289 -0
  138. data/spec/spec_helper.rb +241 -0
  139. metadata +242 -0
@@ -0,0 +1,14 @@
1
+ @ECHO off
2
+
3
+ cd ..\libndtypes
4
+ if exist Makefile nmake /nologo distclean
5
+
6
+ cd tests
7
+ if exist Makefile nmake /nologo distclean
8
+
9
+ cd ..\..\vcbuild
10
+ if exist dist64 rd /q /s dist64
11
+ if exist dist32 rd /q /s dist32
12
+
13
+
14
+
@@ -0,0 +1,1003 @@
1
+ /* Main file for ndtypes ruby wrapper.
2
+ *
3
+ * Author: Sameer Deshmukh (@v0dro)
4
+ */
5
+
6
+ #include "ruby_ndtypes_internal.h"
7
+
8
+ /* ---------- Interal declarations ---------- */
9
+ /* data_type_t variables. */
10
+ static const rb_data_type_t NdtObject_type;
11
+ static const rb_data_type_t ResourceBufferObject_type;
12
+
13
+ /* Class declarations. */
14
+ VALUE cNDTypes;
15
+ VALUE mNDTypes_GCGuard;
16
+ static VALUE cNDTypes_RBuf;
17
+
18
+ static VALUE rb_eValueError;
19
+
20
+ /* ------------------------------------------ */
21
+ /****************************************************************************/
22
+ /* Error handling */
23
+ /****************************************************************************/
24
+
25
+ /* Raise an error stored in $!. Clears it before raising. */
26
+ static void
27
+ raise_error(void)
28
+ {
29
+ VALUE exeception = rb_errinfo();
30
+
31
+ rb_set_errinfo(Qnil);
32
+ rb_exc_raise(exeception);
33
+ }
34
+
35
+ static void
36
+ set_error_info(VALUE err, const char * msg)
37
+ {
38
+ rb_set_errinfo(rb_exc_new2(err, msg));
39
+ }
40
+
41
+ static VALUE
42
+ seterr(ndt_context_t *ctx)
43
+ {
44
+ VALUE exc = rb_eRuntimeError;
45
+
46
+ switch(ctx->err) {
47
+ case NDT_Success: /* should never be set on error */
48
+ exc = rb_eRuntimeError;
49
+ break;
50
+ case NDT_ValueError:
51
+ exc = rb_eValueError;
52
+ break;
53
+ case NDT_TypeError:
54
+ exc = rb_eTypeError;
55
+ break;
56
+ case NDT_InvalidArgumentError:
57
+ exc = rb_eValueError;
58
+ break;
59
+ case NDT_NotImplementedError:
60
+ exc = rb_eNotImpError;
61
+ break;
62
+ case NDT_IndexError:
63
+ exc = rb_eIndexError;
64
+ break;
65
+ case NDT_LexError: case NDT_ParseError:
66
+ exc = rb_eValueError;
67
+ break;
68
+ case NDT_OSError:
69
+ exc = rb_eSysStackError;
70
+ break;
71
+ case NDT_RuntimeError:
72
+ exc = rb_eRuntimeError;
73
+ break;
74
+ case NDT_MemoryError:
75
+ exc = rb_eNoMemError;
76
+ break;
77
+ }
78
+
79
+ set_error_info(exc, ndt_context_msg(ctx));
80
+ ndt_context_del(ctx);
81
+
82
+ return exc;
83
+ }
84
+
85
+ /******************************************************************************/
86
+ /************************* Resource Buffer Object *****************************/
87
+
88
+ /* A ResourceBufferObject is passed around various NDT objects for storing
89
+ * internal state. It might or might not be duplicated across other NDT
90
+ * objects.
91
+ */
92
+ typedef struct ResourceBufferObject {
93
+ ndt_meta_t *m;
94
+ } ResourceBufferObject;
95
+
96
+ #define GET_RBUF(obj, rbuf_p) do { \
97
+ TypedData_Get_Struct((obj), ResourceBufferObject, \
98
+ &ResourceBufferObject_type, (rbuf_p)); \
99
+ } while (0)
100
+ #define RBUF_NDT_M(rbuf_p) ((ndt_meta_t*)(rbuf_p->m))
101
+ #define MAKE_RBUF(self, rbuf_p) TypedData_Make_Struct(self, ResourceBufferObject, \
102
+ &ResourceBufferObject_type, rbuf_p)
103
+ #define WRAP_RBUF(self, rbuf_p) TypedData_Wrap_Struct(self, \
104
+ &ResourceBufferObject_type, rbuf_p)
105
+
106
+ /* GC free the ResourceBufferObject struct. */
107
+ static void
108
+ ResourceBufferObject_dfree(void * self)
109
+ {
110
+ ResourceBufferObject * rbf = (ResourceBufferObject*)self;
111
+
112
+ ndt_meta_del(rbf->m);
113
+ rbf->m = NULL;
114
+ xfree(rbf);
115
+ }
116
+
117
+ /* Calculate the size of the object. */
118
+ static size_t
119
+ ResourceBufferObject_dsize(const void *self)
120
+ {
121
+ return sizeof(ResourceBufferObject);
122
+ }
123
+
124
+ static const rb_data_type_t ResourceBufferObject_type = {
125
+ .wrap_struct_name = "ResourceBufferObject",
126
+ .function = {
127
+ .dmark = 0,
128
+ .dfree = ResourceBufferObject_dfree,
129
+ .dsize = ResourceBufferObject_dsize,
130
+ .reserved = {0,0},
131
+ },
132
+ .parent = 0,
133
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
134
+ };
135
+
136
+ /* FIXME: change this to rbuf_alloc to reflect that its not called by Ruby alloc. */
137
+ static VALUE
138
+ rbuf_allocate(void)
139
+ {
140
+ NDT_STATIC_CONTEXT(ctx);
141
+ ResourceBufferObject *self;
142
+
143
+ self = ALLOC(ResourceBufferObject);
144
+
145
+ self->m = ndt_meta_new(&ctx);
146
+ if (self->m == NULL) {
147
+ rb_raise(rb_eNoMemError, "cannot allocate rbuf object.");
148
+ }
149
+
150
+ return WRAP_RBUF(cNDTypes_RBuf, self);
151
+ }
152
+
153
+ static int
154
+ rbuf_init_from_offset_list(ResourceBufferObject *rbuf, VALUE list)
155
+ {
156
+ ndt_meta_t * const m = rbuf->m;
157
+ VALUE lst;
158
+
159
+ Check_Type(list, T_ARRAY);
160
+
161
+ const int64_t n = RARRAY_LEN(list);
162
+ if (n < 1 || n > NDT_MAX_DIM) {
163
+ rb_raise(rb_eValueError, "number of offset lists must be in [1, %d].",
164
+ NDT_MAX_DIM);
165
+ }
166
+
167
+ m->ndims = 0;
168
+ for (int64_t i = n-1; i >= 0; i--) {
169
+ lst = rb_ary_entry(list, i);
170
+ if (!RB_TYPE_P(lst, T_ARRAY)) {
171
+ rb_raise(rb_eTypeError, "expected a list of offset lists.");
172
+ }
173
+
174
+ const int64_t noffsets = RARRAY_LEN(lst);
175
+ if (noffsets < 2 || noffsets > INT32_MAX) {
176
+ rb_raise(rb_eValueError, "length of a single offset must be in [2, INT32_MAX].");
177
+ }
178
+
179
+ int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
180
+ if (offsets == NULL) {
181
+ rb_raise(rb_eNoMemError, "could not allocate offsets.");
182
+ }
183
+
184
+ for (int32_t k = 0; k < noffsets; k++) {
185
+ long long x = NUM2LL(rb_ary_entry(lst, k));
186
+ if (x == -1 || x < 0 || x > INT32_MAX) {
187
+ ndt_free(offsets);
188
+ rb_raise(rb_eValueError, "offset must be in [0, INT32_MAX].");
189
+ }
190
+
191
+ offsets[k] = (int32_t)x;
192
+ }
193
+
194
+ m->noffsets[m->ndims] = (int32_t)noffsets;
195
+ m->offsets[m->ndims] = offsets;
196
+ m->ndims++;
197
+ }
198
+
199
+ return 0;
200
+ }
201
+
202
+ static VALUE
203
+ rbuf_from_offset_lists(VALUE list)
204
+ {
205
+ VALUE rbuf;
206
+ ResourceBufferObject * rbuf_p;
207
+
208
+ rbuf = rbuf_allocate();
209
+ GET_RBUF(rbuf, rbuf_p);
210
+ rbuf_init_from_offset_list(rbuf_p, list);
211
+
212
+ return rbuf;
213
+ }
214
+
215
+ /******************************************************************************/
216
+
217
+ /******************************************************************************/
218
+ /************************* NDT struct object **********************************/
219
+
220
+ typedef struct NdtObject {
221
+ VALUE rbuf; /* resource buffer */
222
+ ndt_t *ndt; /* type */
223
+ } NdtObject;
224
+
225
+ #define NDT(v) (((NdtObject *)v)->ndt)
226
+ #define RBUF(v) (((NdtObject *)v)->rbuf)
227
+ #define GET_NDT(obj, ndt_p) do { \
228
+ TypedData_Get_Struct((obj), NdtObject, \
229
+ &NdtObject_type, (ndt_p)); \
230
+ } while (0)
231
+ #define MAKE_NDT(self, ndt_p) TypedData_Make_Struct(self, NdtObject, \
232
+ &NdtObject_type, ndt_p)
233
+ #define WRAP_NDT(self, ndt_p) TypedData_Wrap_Struct(self, &NdtObject_type, ndt_p)
234
+ #define NDT_CHECK_TYPE(obj) (CLASS_OF(obj) == cNDTypes)
235
+
236
+ /* Get the metatdata of the ResourceBufferObject within this NDT Ruby object. */
237
+ static ndt_meta_t *
238
+ rbuf_ndt_meta(VALUE ndt)
239
+ {
240
+ NdtObject *ndt_p;
241
+ ResourceBufferObject *rbuf_p;
242
+
243
+ GET_NDT(ndt, ndt_p);
244
+ GET_RBUF(ndt_p->rbuf, rbuf_p);
245
+
246
+ return rbuf_p->m;
247
+ }
248
+
249
+ /* Allocate an NdtObject, initialize members and return wrapped as a Ruby object. */
250
+ static VALUE
251
+ NdtObject_alloc(void)
252
+ {
253
+ NdtObject *ndt_p;
254
+
255
+ ndt_p = ZALLOC(NdtObject);
256
+
257
+ ndt_p->rbuf = 0;
258
+ ndt_p->ndt = NULL;
259
+
260
+ return WRAP_NDT(cNDTypes, ndt_p);
261
+ }
262
+
263
+ /* GC mark the NdtObject struct. */
264
+ /* TODO: verify that there are no more object allocations happening inside ndt. */
265
+ static void
266
+ NdtObject_dmark(void * self)
267
+ {
268
+ NdtObject * ndt = (NdtObject*)self;
269
+
270
+ rb_gc_mark(ndt->rbuf);
271
+ }
272
+
273
+ /* GC free the NdtObject struct. */
274
+ static void
275
+ NdtObject_dfree(void * self)
276
+ {
277
+ NdtObject * ndt = (NdtObject*)self;
278
+
279
+ rb_ndtypes_gc_guard_unregister(ndt);
280
+ xfree(ndt);
281
+ }
282
+
283
+ /* Calculate the size of the object. */
284
+ static size_t
285
+ NdtObject_dsize(const void *self)
286
+ {
287
+ return sizeof(NdtObject);
288
+ }
289
+
290
+ static const rb_data_type_t NdtObject_type = {
291
+ .wrap_struct_name = "NdtObject",
292
+ .function = {
293
+ .dmark = NdtObject_dmark,
294
+ .dfree = NdtObject_dfree,
295
+ .dsize = NdtObject_dsize,
296
+ .reserved = {0,0},
297
+ },
298
+ .parent = 0,
299
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
300
+ };
301
+
302
+ /* Allocate an NDT object and return a Ruby object. Used for Ruby class initialization. */
303
+ static VALUE
304
+ NDTypes_allocate(VALUE self)
305
+ {
306
+ NdtObject *ndt;
307
+
308
+ return MAKE_NDT(self, ndt);
309
+ }
310
+ /******************************************************************************/
311
+
312
+ #define NDTYPES_BOOL_FUNC(NDTFUNC) \
313
+ static VALUE \
314
+ NDTypes_##NDTFUNC(VALUE self) \
315
+ { \
316
+ NdtObject *ndt_p; \
317
+ GET_NDT(self, ndt_p); \
318
+ if (NDTFUNC(NDT(ndt_p))) { \
319
+ return Qtrue; \
320
+ } \
321
+ return Qfalse; \
322
+ }
323
+
324
+ NDTYPES_BOOL_FUNC(ndt_is_abstract)
325
+ NDTYPES_BOOL_FUNC(ndt_is_concrete)
326
+
327
+ NDTYPES_BOOL_FUNC(ndt_is_optional)
328
+ NDTYPES_BOOL_FUNC(ndt_is_scalar)
329
+ NDTYPES_BOOL_FUNC(ndt_is_signed)
330
+ NDTYPES_BOOL_FUNC(ndt_is_unsigned)
331
+ NDTYPES_BOOL_FUNC(ndt_is_float)
332
+ NDTYPES_BOOL_FUNC(ndt_is_complex)
333
+
334
+ NDTYPES_BOOL_FUNC(ndt_is_c_contiguous)
335
+ NDTYPES_BOOL_FUNC(ndt_is_f_contiguous)
336
+
337
+ static VALUE
338
+ NDTypes_from_object(VALUE self, VALUE type)
339
+ {
340
+ NDT_STATIC_CONTEXT(ctx);
341
+ const char *cp;
342
+ NdtObject *ndt_p;
343
+
344
+ if (NDT_CHECK_TYPE(type)) {
345
+ return rb_funcall(type, rb_intern("dup"), 0, NULL);
346
+ }
347
+
348
+ cp = StringValuePtr(type);
349
+
350
+ GET_NDT(self, ndt_p);
351
+ RBUF(ndt_p) = rbuf_allocate();
352
+ if (RBUF(ndt_p) == NULL) {
353
+ rb_raise(rb_eNoMemError, "problem in allocating RBUF object.");
354
+ }
355
+
356
+ rb_ndtypes_gc_guard_register(ndt_p, RBUF(ndt_p));
357
+
358
+ NDT(ndt_p) = ndt_from_string_fill_meta(rbuf_ndt_meta(self), cp, &ctx);
359
+ if (NDT(ndt_p) == NULL) {
360
+ seterr(&ctx);
361
+ raise_error();
362
+ }
363
+
364
+ return self;
365
+ }
366
+
367
+ static VALUE
368
+ NDTypes_from_offsets_and_dtype(VALUE offsets, VALUE type)
369
+ {
370
+ NDT_STATIC_CONTEXT(ctx);
371
+ VALUE self;
372
+ NdtObject *self_p;
373
+ const char *cp;
374
+
375
+ Check_Type(type, T_STRING);
376
+
377
+ cp = StringValuePtr(type);
378
+
379
+ self = NdtObject_alloc();
380
+ GET_NDT(self, self_p);
381
+ RBUF(self_p) = rbuf_from_offset_lists(offsets);
382
+ NDT(self_p) = ndt_from_metadata_and_dtype(rbuf_ndt_meta(self_p), cp, &ctx);
383
+
384
+ rb_ndtypes_gc_guard_register(self_p, RBUF(self_p));
385
+
386
+ return self;
387
+ }
388
+
389
+ /* Initialize an instance of an NDTypes object. */
390
+ static VALUE
391
+ NDTypes_initialize(int argc, VALUE *argv, VALUE self)
392
+ {
393
+ NdtObject *ndt_p;
394
+ VALUE offsets = Qnil, type;
395
+
396
+ if (argc < 1) {
397
+ rb_raise(rb_eArgError, "expected atleast type. offset optional. Number of args: %d.",
398
+ argc);
399
+ }
400
+
401
+ type = argv[0];
402
+ if (argc == 2) {
403
+ offsets = argv[1];
404
+ }
405
+
406
+ if (offsets == Qnil) {
407
+ return NDTypes_from_object(self, type);
408
+ }
409
+
410
+ return NDTypes_from_offsets_and_dtype(offsets, type);
411
+ }
412
+
413
+ /* String representation of the type. */
414
+ static VALUE
415
+ NDTypes_to_s(VALUE self)
416
+ {
417
+ NDT_STATIC_CONTEXT(ctx);
418
+ char *cp;
419
+ NdtObject *ndt;
420
+ VALUE str;
421
+
422
+ GET_NDT(self, ndt);
423
+ cp = ndt_as_string(NDT(ndt), &ctx);
424
+ if (cp == NULL) {
425
+ seterr(&ctx);
426
+ raise_error();
427
+ }
428
+
429
+ str = rb_str_new_cstr(cp);
430
+ ndt_free(cp);
431
+
432
+ return str;
433
+ }
434
+
435
+ /* Serialize the NDTypes object into a byte string. */
436
+ static VALUE
437
+ NDTypes_serialize(VALUE self)
438
+ {
439
+ NdtObject *ndt;
440
+ char *bytes;
441
+ int64_t size;
442
+ VALUE str;
443
+
444
+ NDT_STATIC_CONTEXT(ctx);
445
+ GET_NDT(self, ndt);
446
+
447
+ size = ndt_serialize(&bytes, NDT(ndt), &ctx);
448
+ if (size < 0) {
449
+ seterr(&ctx);
450
+ raise_error();
451
+ }
452
+
453
+ str = rb_usascii_str_new(bytes, size);
454
+ ndt_free(bytes);
455
+
456
+ return str;
457
+ }
458
+
459
+ /* Implement #ndim */
460
+ static VALUE
461
+ NDTypes_ndim(VALUE self)
462
+ {
463
+ NdtObject *ndt_p;
464
+
465
+ GET_NDT(self, ndt_p);
466
+
467
+ const ndt_t *t = NDT(ndt_p);
468
+
469
+ if (ndt_is_abstract(t)) {
470
+ rb_raise(rb_eTypeError, "abstract type has no ndim.");
471
+ }
472
+
473
+ return LL2NUM(t->ndim);
474
+ }
475
+
476
+ /* #datasize */
477
+ static VALUE
478
+ NDTypes_datasize(VALUE self)
479
+ {
480
+ NdtObject *ndt_p;
481
+
482
+ GET_NDT(self, ndt_p);
483
+
484
+ const ndt_t *t = NDT(ndt_p);
485
+
486
+ if (ndt_is_abstract(t)) {
487
+ rb_raise(rb_eTypeError, "abstract type has no datasize.");
488
+ }
489
+
490
+ return LL2NUM(t->datasize);
491
+ }
492
+
493
+ /* #itemsize */
494
+ static VALUE
495
+ NDTypes_itemsize(VALUE self)
496
+ {
497
+ NdtObject *ndt_p;
498
+ int64_t size;
499
+
500
+ GET_NDT(self, ndt_p);
501
+
502
+ const ndt_t *t = NDT(ndt_p);
503
+
504
+ if (ndt_is_abstract(t)) {
505
+ rb_raise(rb_eTypeError, "abstract type has no datasize.");
506
+ }
507
+
508
+ switch (t->tag) {
509
+ case FixedDim:
510
+ size = t->Concrete.FixedDim.itemsize;
511
+ break;
512
+ case VarDim:
513
+ size = t->Concrete.VarDim.itemsize;
514
+ break;
515
+ default:
516
+ size = t->datasize;
517
+ break;
518
+ }
519
+
520
+ return LL2NUM(size);
521
+ }
522
+
523
+ /* Implement #align */
524
+ static VALUE
525
+ NDTypes_align(VALUE self)
526
+ {
527
+ NdtObject *ndt_p;
528
+
529
+ GET_NDT(self, ndt_p);
530
+
531
+ const ndt_t *t = NDT(ndt_p);
532
+
533
+ if (ndt_is_abstract(t)) {
534
+ rb_raise(rb_eTypeError, "abstract type has no datasize.");
535
+ }
536
+
537
+ return LL2NUM(t->align);
538
+ }
539
+
540
+ static int
541
+ NDTypes_compare(VALUE left, VALUE right)
542
+ {
543
+ NdtObject *left_p = NULL, *right_p = NULL;
544
+
545
+ GET_NDT(left, left_p);
546
+ GET_NDT(right, right_p);
547
+
548
+ return ndt_equal(NDT(left_p), NDT(right_p));
549
+ }
550
+
551
+ /* Implement #== operator */
552
+ static VALUE
553
+ NDTypes_eqeq(VALUE self, VALUE other)
554
+ {
555
+ if (!NDT_CHECK_TYPE(other)) {
556
+ return Qfalse;
557
+ }
558
+
559
+ int r = NDTypes_compare(self, other);
560
+
561
+ if (r == 0) { /* not equal */
562
+ return Qfalse;
563
+ }
564
+ else { /* equal */
565
+ return Qtrue;
566
+ }
567
+ }
568
+
569
+ /* Implemented #!= operator */
570
+ static VALUE
571
+ NDTypes_neq(VALUE self, VALUE other)
572
+ {
573
+ if (!NDT_CHECK_TYPE(other)) {
574
+ return Qfalse;
575
+ }
576
+
577
+ int r = NDTypes_compare(self, other);
578
+
579
+ if (r == 0) { /* not equal */
580
+ return Qtrue;
581
+ }
582
+ else { /* equal */
583
+ return Qfalse;
584
+ }
585
+ }
586
+
587
+ /* Implement NDT#hidden_dtype */
588
+ static VALUE
589
+ NDTypes_hidden_dtype(VALUE self)
590
+ {
591
+ NDT_STATIC_CONTEXT(ctx);
592
+ NdtObject *self_p;
593
+
594
+ GET_NDT(self, self_p);
595
+
596
+ const ndt_t *t = NDT(self_p);
597
+ const ndt_t *dtype;
598
+ ndt_t *u;
599
+
600
+ dtype = ndt_hidden_dtype(t);
601
+
602
+ u = ndt_copy(dtype, &ctx);
603
+ if (u == NULL) {
604
+ seterr(&ctx);
605
+ raise_error();
606
+ }
607
+
608
+ return rb_ndtypes_from_type(u);
609
+ }
610
+
611
+ static VALUE
612
+ NDTypes_match(VALUE self, VALUE other)
613
+ {
614
+ NDT_STATIC_CONTEXT(ctx);
615
+ int res;
616
+ NdtObject *self_p, *other_p;
617
+
618
+ if (!NDT_CHECK_TYPE(other)) {
619
+ rb_raise(rb_eTypeError, "argument must be of type NDT.");
620
+ }
621
+
622
+ GET_NDT(self, self_p);
623
+ GET_NDT(other, other_p);
624
+
625
+ res = ndt_match(NDT(self_p), NDT(other_p), &ctx);
626
+ if (res == -1) {
627
+ seterr(&ctx);
628
+ raise_error();
629
+ }
630
+
631
+ return INT2BOOL(res);
632
+ }
633
+
634
+ static VALUE
635
+ NDTypes_ast(VALUE self)
636
+ {
637
+ NDT_STATIC_CONTEXT(ctx);
638
+ VALUE result;
639
+ char *cp;
640
+ NdtObject *self_p;
641
+
642
+ GET_NDT(self, self_p);
643
+
644
+ cp = ndt_ast_repr(NDT(self_p), &ctx);
645
+ if (cp == NULL) {
646
+ seterr(&ctx);
647
+ raise_error();
648
+ }
649
+
650
+ result = rb_str_new2(cp);
651
+ ndt_free(cp);
652
+
653
+ return result;
654
+ }
655
+
656
+ static VALUE
657
+ NDTypes_pretty(VALUE self)
658
+ {
659
+ NDT_STATIC_CONTEXT(ctx);
660
+ char *cp;
661
+ NdtObject *self_p;
662
+ VALUE result;
663
+
664
+ GET_NDT(self, self_p);
665
+
666
+ cp = ndt_indent(NDT(self_p), &ctx);
667
+ if (cp == NULL) {
668
+ seterr(&ctx);
669
+ raise_error();
670
+ }
671
+
672
+ result = rb_str_new2(cp);
673
+ ndt_free(cp);
674
+
675
+ return result;
676
+ }
677
+
678
+ /****************************************************************************/
679
+ /* Class methods */
680
+ /****************************************************************************/
681
+
682
+ /* Deserialize a byte string into an NDTypes object. */
683
+ static VALUE
684
+ NDTypes_s_deserialize(VALUE klass, VALUE str)
685
+ {
686
+ NdtObject *ndt_p;
687
+ ResourceBufferObject *rbuf_p;
688
+ VALUE ndt, rbuf;
689
+ char *cp;
690
+ int64_t len;
691
+ NDT_STATIC_CONTEXT(ctx);
692
+
693
+ Check_Type(str, T_STRING);
694
+
695
+ cp = StringValuePtr(str);
696
+ if (cp == NULL) {
697
+ // raise
698
+ }
699
+ len = RSTRING_LEN(str);
700
+
701
+ rbuf_p = ALLOC(ResourceBufferObject);
702
+ rbuf_p->m = ndt_meta_new(&ctx);
703
+ if (rbuf_p->m == NULL) {
704
+ /* TODO: cannot alloc meta data */
705
+ }
706
+
707
+ ndt_p = ALLOC(NdtObject);
708
+ NDT(ndt_p) = ndt_deserialize(RBUF_NDT_M(rbuf_p), cp, len, &ctx);
709
+ if (NDT(ndt_p) == NULL) {
710
+ /* TODO: raise error for cannot deserialize */
711
+ }
712
+
713
+ rbuf = WRAP_RBUF(cNDTypes_RBuf, rbuf_p);
714
+ RBUF(ndt_p) = rbuf;
715
+ rb_ndtypes_gc_guard_register(ndt_p, rbuf);
716
+ ndt = WRAP_NDT(cNDTypes, ndt_p);
717
+
718
+ return ndt;
719
+ }
720
+
721
+ /* Create a typedef */
722
+ static VALUE
723
+ NDTypes_s_typedef(VALUE klass, VALUE new_type, VALUE old_type)
724
+ {
725
+ NDT_STATIC_CONTEXT(ctx);
726
+ const char *cname, *ctype;
727
+ ndt_t *t;
728
+
729
+ Check_Type(new_type, T_STRING);
730
+ Check_Type(old_type, T_STRING);
731
+
732
+ cname = StringValueCStr(new_type);
733
+ if (cname == NULL) {
734
+
735
+ }
736
+
737
+ ctype = StringValueCStr(old_type);
738
+ if (ctype == NULL) {
739
+
740
+ }
741
+
742
+ t = ndt_from_string(ctype, &ctx);
743
+ if (t == NULL) {
744
+
745
+ }
746
+
747
+ if (ndt_typedef(cname, t, NULL, &ctx) < 0) {
748
+
749
+ }
750
+
751
+ return Qnil;
752
+ }
753
+
754
+ /* Instatiate ndtypes object using typedef'd type and another NDTypes object. */
755
+ static VALUE
756
+ NDTypes_s_instantiate(VALUE klass, VALUE name, VALUE type)
757
+ {
758
+ const char *cname;
759
+ char *cp;
760
+ ndt_t *t, *tp;
761
+ NdtObject *type_p;
762
+ NDT_STATIC_CONTEXT(ctx);
763
+
764
+ Check_Type(name, T_STRING);
765
+
766
+ cname = StringValuePtr(name);
767
+
768
+ if (!NDT_CHECK_TYPE(type)) {
769
+ rb_raise(rb_eTypeError, "type argument must be ndt.");
770
+ }
771
+
772
+ cp = ndt_strdup(cname, &ctx);
773
+ if (cp == NULL) {
774
+ seterr(&ctx);
775
+ raise_error();
776
+ }
777
+
778
+ GET_NDT(type, type_p);
779
+
780
+ tp = ndt_copy(NDT(type_p), &ctx);
781
+ if (tp == NULL) {
782
+ ndt_free(cp);
783
+ seterr(&ctx);
784
+ raise_error();
785
+ }
786
+
787
+ t = ndt_nominal(cp, tp, &ctx);
788
+ if (t == NULL) {
789
+ seterr(&ctx);
790
+ raise_error();
791
+ }
792
+
793
+ return rb_ndtypes_move_subtree(type, t);
794
+ }
795
+
796
+ /****************************************************************************/
797
+ /* Public C API */
798
+ /****************************************************************************/
799
+
800
+ /* Create NDT object from ndt_t type struct. */
801
+ VALUE
802
+ rb_ndtypes_from_type(ndt_t *type)
803
+ {
804
+ VALUE self;
805
+ NdtObject *self_p;
806
+
807
+ self = NdtObject_alloc();
808
+ GET_NDT(self, self_p);
809
+
810
+ NDT(self_p) = type;
811
+
812
+ return self;
813
+ }
814
+
815
+ /* Return 1 if obj is of type NDTypes. 0 otherwise. */
816
+ int
817
+ rb_ndtypes_check_type(VALUE obj)
818
+ {
819
+ return NDT_CHECK_TYPE(obj);
820
+ }
821
+
822
+ /* Get a pointer to the NdtObject struct that is contained within obj. */
823
+ NdtObject *
824
+ rb_ndtypes_get_ndt_object(VALUE obj)
825
+ {
826
+ NdtObject *ndt_p;
827
+
828
+ if (!NDT_CHECK_TYPE(obj)) {
829
+ /* raise error */
830
+ }
831
+
832
+ GET_NDT(obj, ndt_p);
833
+
834
+ return ndt_p;
835
+ }
836
+
837
+ /* Get an allocated Ruby object of type NDTypes. ndt_p should have been allocated already. */
838
+ VALUE
839
+ rb_ndtypes_make_ndt_object(NdtObject *ndt_p)
840
+ {
841
+ return MAKE_NDT(cNDTypes, ndt_p);
842
+ }
843
+
844
+ /* Perform allocation and get a Ruby object of type NDTypes. */
845
+ VALUE
846
+ rb_ndtypes_wrap_ndt_object(void)
847
+ {
848
+ NdtObject *ndt_p = NULL;
849
+
850
+ return WRAP_NDT(cNDTypes, ndt_p);
851
+ }
852
+
853
+ /* Get pointer to the internal ndt_t object from the NDTypes Ruby object ndt. */
854
+ const ndt_t *
855
+ rb_ndtypes_const_ndt(VALUE ndt)
856
+ {
857
+ NdtObject *ndt_p;
858
+
859
+ if(!NDT_CHECK_TYPE(ndt)) {
860
+ rb_raise(rb_eArgError, "must be NDT");
861
+ }
862
+
863
+ GET_NDT(ndt, ndt_p);
864
+
865
+ return ndt_p->ndt;
866
+ }
867
+
868
+ /* Function for taking a source type and moving it accross the subtree.
869
+
870
+ @param src NDTypes Ruby object of the source XND object.
871
+ @param t Pointer to type of the view of XND object.
872
+ */
873
+ VALUE
874
+ rb_ndtypes_move_subtree(VALUE src, ndt_t *t)
875
+ {
876
+ NDT_STATIC_CONTEXT(ctx);
877
+ VALUE dest;
878
+ NdtObject *dest_p, *src_p;
879
+
880
+ if (!NDT_CHECK_TYPE(src)) {
881
+ rb_raise(rb_eArgError, "expected NDT object from view src.");
882
+ }
883
+
884
+ dest = NdtObject_alloc();
885
+
886
+ GET_NDT(dest, dest_p);
887
+ NDT(dest_p) = ndt_copy(t, &ctx);
888
+ if (NDT(dest_p) == NULL) {
889
+ rb_raise(rb_eNoMemError, "could not allocate memory for ndt_copy().");
890
+ }
891
+
892
+ GET_NDT(src, src_p);
893
+ RBUF(dest_p) = RBUF(src_p);
894
+
895
+ rb_ndtypes_gc_guard_register(dest_p, RBUF(dest_p));
896
+
897
+ return dest;
898
+ }
899
+
900
+ /* Create NDT object from String. Returns the same object if type is NDT.
901
+
902
+ @param type String object containing description of type.
903
+ @return New NDT object.
904
+ */
905
+ VALUE
906
+ rb_ndtypes_from_object(VALUE type)
907
+ {
908
+ NDT_STATIC_CONTEXT(ctx);
909
+ VALUE copy;
910
+ NdtObject *copy_p;
911
+ const char *cp;
912
+
913
+ if (NDT_CHECK_TYPE(type)) {
914
+ return type;
915
+ }
916
+
917
+ Check_Type(type, T_STRING);
918
+
919
+ cp = StringValuePtr(type);
920
+ if (cp == NULL) {
921
+ rb_raise(rb_eNoMemError,
922
+ "error is getting C string from type in rb_ndtypes_from_object.");
923
+ }
924
+
925
+ copy = NdtObject_alloc();
926
+ GET_NDT(copy, copy_p);
927
+
928
+ RBUF(copy_p) = rbuf_allocate();
929
+ NDT(copy_p) = ndt_from_string_fill_meta(
930
+ rbuf_ndt_meta(copy),
931
+ cp, &ctx);
932
+ if (NDT(copy_p) == NULL) {
933
+ seterr(&ctx);
934
+ raise_error();
935
+ }
936
+ rb_ndtypes_gc_guard_register(copy_p, RBUF(copy_p));
937
+
938
+ return copy;
939
+ }
940
+
941
+ VALUE
942
+ rb_ndtypes_set_error(ndt_context_t *ctx)
943
+ {
944
+ return seterr(ctx);
945
+ }
946
+
947
+ void Init_ruby_ndtypes(void)
948
+ {
949
+ NDT_STATIC_CONTEXT(ctx);
950
+
951
+ /* initialize NDT internals */
952
+ ndt_init(&ctx);
953
+
954
+ /* define classes */
955
+ cNDTypes = rb_define_class("NDTypes", rb_cObject);
956
+ cNDTypes_RBuf = rb_define_class_under(cNDTypes, "RBuf", rb_cObject);
957
+ mNDTypes_GCGuard = rb_define_module_under(cNDTypes, "GCGuard");
958
+
959
+ /* errors */
960
+ rb_eValueError = rb_define_class("ValueError", rb_eRuntimeError);
961
+
962
+ /* Initializers */
963
+ rb_define_alloc_func(cNDTypes, NDTypes_allocate);
964
+ rb_define_method(cNDTypes, "initialize", NDTypes_initialize, -1);
965
+
966
+ /* Instance methods */
967
+ rb_define_method(cNDTypes, "serialize", NDTypes_serialize, 0);
968
+ rb_define_method(cNDTypes, "ndim", NDTypes_ndim, 0);
969
+ rb_define_method(cNDTypes, "itemsize", NDTypes_itemsize, 0);
970
+ rb_define_method(cNDTypes, "datasize", NDTypes_datasize, 0);
971
+ rb_define_method(cNDTypes, "align", NDTypes_align, 0);
972
+ rb_define_method(cNDTypes, "to_s", NDTypes_to_s, 0);
973
+ rb_define_method(cNDTypes, "hidden_dtype", NDTypes_hidden_dtype, 0);
974
+ rb_define_method(cNDTypes, "match", NDTypes_match, 1);
975
+ rb_define_method(cNDTypes, "ast", NDTypes_ast, 0);
976
+ rb_define_method(cNDTypes, "pretty", NDTypes_pretty, 0);
977
+
978
+ /* Boolean functions */
979
+ rb_define_method(cNDTypes, "concrete?", NDTypes_ndt_is_concrete, 0);
980
+ rb_define_method(cNDTypes, "abstract?", NDTypes_ndt_is_abstract, 0);
981
+ rb_define_method(cNDTypes, "optional?", NDTypes_ndt_is_optional, 0);
982
+ rb_define_method(cNDTypes, "scalar?", NDTypes_ndt_is_scalar, 0);
983
+ rb_define_method(cNDTypes, "signed?", NDTypes_ndt_is_signed, 0);
984
+ rb_define_method(cNDTypes, "unsigned?", NDTypes_ndt_is_unsigned, 0);
985
+ rb_define_method(cNDTypes, "float?", NDTypes_ndt_is_float, 0);
986
+ rb_define_method(cNDTypes, "complex?", NDTypes_ndt_is_complex, 0);
987
+ rb_define_method(cNDTypes, "c_contiguous?", NDTypes_ndt_is_c_contiguous, 0);
988
+ rb_define_method(cNDTypes, "f_contiguous?", NDTypes_ndt_is_f_contiguous, 0);
989
+ rb_define_method(cNDTypes, "==", NDTypes_eqeq, 1);
990
+ rb_define_method(cNDTypes, "!=", NDTypes_neq, 1);
991
+
992
+ /* Class methods */
993
+ rb_define_singleton_method(cNDTypes, "deserialize", NDTypes_s_deserialize, 1);
994
+ rb_define_singleton_method(cNDTypes, "typedef", NDTypes_s_typedef, 2);
995
+ rb_define_singleton_method(cNDTypes, "instantiate", NDTypes_s_instantiate, 2);
996
+
997
+ /* Constants */
998
+ rb_define_const(cNDTypes, "MAX_DIM", INT2NUM(NDT_MAX_DIM));
999
+
1000
+ /* GC guard init */
1001
+ rb_ndtypes_init_gc_guard();
1002
+ }
1003
+