autoc 1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +3 -0
  3. data/README.md +149 -0
  4. data/cmake/AutoC.cmake +39 -0
  5. data/lib/autoc/allocators.rb +51 -0
  6. data/lib/autoc/association.rb +126 -0
  7. data/lib/autoc/box.rb +311 -0
  8. data/lib/autoc/cmake.rb +54 -0
  9. data/lib/autoc/collection.rb +83 -110
  10. data/lib/autoc/composite.rb +333 -0
  11. data/lib/autoc/cstring.rb +263 -0
  12. data/lib/autoc/function.rb +247 -0
  13. data/lib/autoc/hash_map.rb +328 -0
  14. data/lib/autoc/hash_set.rb +339 -0
  15. data/lib/autoc/hashers.rb +102 -0
  16. data/lib/autoc/list.rb +444 -0
  17. data/lib/autoc/module.rb +434 -0
  18. data/lib/autoc/openmp.rb +15 -0
  19. data/lib/autoc/primitive.rb +27 -0
  20. data/lib/autoc/ranges.rb +707 -0
  21. data/lib/autoc/record.rb +247 -0
  22. data/lib/autoc/scaffold/docs.rb +117 -0
  23. data/lib/autoc/scaffold/generic_value.rb +86 -0
  24. data/lib/autoc/scaffold/project.rb +75 -0
  25. data/lib/autoc/scaffold/test_cstring.rb +113 -0
  26. data/lib/autoc/scaffold/test_cstring_hash_set.rb +35 -0
  27. data/lib/autoc/scaffold/test_int_box.rb +22 -0
  28. data/lib/autoc/scaffold/test_int_hash_set.rb +448 -0
  29. data/lib/autoc/scaffold/test_int_list.rb +106 -0
  30. data/lib/autoc/scaffold/test_int_vector.rb +83 -0
  31. data/lib/autoc/scaffold/test_v2v_hash_map.rb +83 -0
  32. data/lib/autoc/scaffold/test_value_hash_set.rb +60 -0
  33. data/lib/autoc/scaffold/test_value_vector.rb +146 -0
  34. data/{test/test.rb → lib/autoc/scaffold/tests.rb} +179 -158
  35. data/lib/autoc/scaffold.rb +12 -0
  36. data/lib/autoc/sequential.rb +99 -0
  37. data/lib/autoc/set.rb +331 -0
  38. data/lib/autoc/std.rb +149 -0
  39. data/lib/autoc/type.rb +93 -531
  40. data/lib/autoc/vector.rb +290 -0
  41. data/lib/autoc.rb +4 -35
  42. metadata +55 -85
  43. data/.yardopts +0 -4
  44. data/CHANGES +0 -23
  45. data/README +0 -28
  46. data/doc/AutoC/Code.html +0 -523
  47. data/doc/AutoC/Collection.html +0 -1214
  48. data/doc/AutoC/HashMap.html +0 -1441
  49. data/doc/AutoC/HashSet.html +0 -916
  50. data/doc/AutoC/Iterators/Bidirectional.html +0 -204
  51. data/doc/AutoC/Iterators/Unidirectional.html +0 -200
  52. data/doc/AutoC/Iterators.html +0 -126
  53. data/doc/AutoC/List.html +0 -1039
  54. data/doc/AutoC/Maps.html +0 -290
  55. data/doc/AutoC/Module/File.html +0 -415
  56. data/doc/AutoC/Module/Header.html +0 -437
  57. data/doc/AutoC/Module/Source.html +0 -707
  58. data/doc/AutoC/Module.html +0 -948
  59. data/doc/AutoC/Priority.html +0 -138
  60. data/doc/AutoC/Queue.html +0 -1172
  61. data/doc/AutoC/Reference.html +0 -735
  62. data/doc/AutoC/Sets.html +0 -520
  63. data/doc/AutoC/String.html +0 -1394
  64. data/doc/AutoC/TreeMap.html +0 -1565
  65. data/doc/AutoC/TreeSet.html +0 -1447
  66. data/doc/AutoC/Type.html +0 -2148
  67. data/doc/AutoC/UserDefinedType.html +0 -1047
  68. data/doc/AutoC/Vector.html +0 -987
  69. data/doc/AutoC.html +0 -331
  70. data/doc/_index.html +0 -388
  71. data/doc/class_list.html +0 -51
  72. data/doc/css/common.css +0 -1
  73. data/doc/css/full_list.css +0 -58
  74. data/doc/css/style.css +0 -481
  75. data/doc/file.CHANGES.html +0 -117
  76. data/doc/file.README.html +0 -116
  77. data/doc/file_list.html +0 -61
  78. data/doc/frames.html +0 -17
  79. data/doc/index.html +0 -116
  80. data/doc/js/app.js +0 -243
  81. data/doc/js/full_list.js +0 -216
  82. data/doc/js/jquery.js +0 -4
  83. data/doc/method_list.html +0 -1307
  84. data/doc/top-level-namespace.html +0 -112
  85. data/lib/autoc/code.rb +0 -237
  86. data/lib/autoc/collection/hash_map.rb +0 -385
  87. data/lib/autoc/collection/hash_set.rb +0 -337
  88. data/lib/autoc/collection/iterator.rb +0 -39
  89. data/lib/autoc/collection/list.rb +0 -429
  90. data/lib/autoc/collection/map.rb +0 -41
  91. data/lib/autoc/collection/queue.rb +0 -517
  92. data/lib/autoc/collection/set.rb +0 -134
  93. data/lib/autoc/collection/tree_map.rb +0 -464
  94. data/lib/autoc/collection/tree_set.rb +0 -611
  95. data/lib/autoc/collection/vector.rb +0 -336
  96. data/lib/autoc/string.rb +0 -492
  97. data/test/test_auto.c +0 -7141
  98. data/test/test_auto.h +0 -753
  99. data/test/test_char_string.rb +0 -270
  100. data/test/test_int_list.rb +0 -35
  101. data/test/test_int_tree_set.rb +0 -111
  102. data/test/test_int_vector.rb +0 -34
  103. data/test/test_value_hash_map.rb +0 -162
  104. data/test/test_value_hash_set.rb +0 -173
  105. data/test/test_value_list.rb +0 -193
  106. data/test/test_value_queue.rb +0 -275
  107. data/test/test_value_tree_map.rb +0 -176
  108. data/test/test_value_tree_set.rb +0 -173
  109. data/test/test_value_vector.rb +0 -155
  110. data/test/value.rb +0 -80
data/lib/autoc/set.rb ADDED
@@ -0,0 +1,331 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'autoc/collection'
5
+
6
+
7
+ module AutoC
8
+
9
+
10
+ class Set < Collection
11
+
12
+ def orderable? = false # No idea how to compute the ordering of this container
13
+
14
+ def initialize(*args, set_operations: true, **kws)
15
+ super(*args, **kws)
16
+ @set_operations = set_operations # Instruct to emit standard set operations (conjunction, disjunction etc.)
17
+ end
18
+
19
+ private
20
+
21
+ def configure
22
+ super
23
+ method(:int, :put, { target: rvalue, value: element.const_rvalue }, constraint:-> { element.copyable? && element.comparable? }).configure do
24
+ header %{
25
+ @brief Put a value
26
+
27
+ @param[in] target set to put into
28
+ @param[in] value value to put
29
+ @return non-zero value on successful put and zero value and zero value otherwise
30
+
31
+ This function puts a *copy* of the specified `value` to the set only if there is no equavalent element in the set.
32
+ The returned value indicates whether a new value in put or the set already contains an equivalent element.
33
+
34
+ After call to this function the set will contain an element equivalent to the `value` which is either the already contained element or a copy of the specified `value`.
35
+
36
+ The function requires the element's type to be both *comparable* and *copyable*.
37
+
38
+ @since 2.0
39
+ }
40
+ end
41
+ method(:int, :push, { target: rvalue, value: element.const_rvalue }, constraint:-> { element.copyable? && element.comparable? }).configure do
42
+ header %{
43
+ @brief Force put a value
44
+
45
+ @param[in] target set to put into
46
+ @param[in] value value to put
47
+ @return non-zero value if a value was replaced or zero value if a new value was inserted
48
+
49
+ This function puts a *copy* of the specified `value` to the set replacing already contained element if the is one.
50
+ The return value indicates whether this is a replacement of an already contained element or a put of a new element.
51
+
52
+ After call to this function the set will contain an element equivalent to the `value`.
53
+
54
+ The function requires the element's type to be both *comparable* and *copyable*.
55
+
56
+ @since 2.0
57
+ }
58
+ end
59
+ method(:int, :remove, { target: rvalue, value: element.const_rvalue }, constraint:-> { element.comparable? }).configure do
60
+ header %{
61
+ @brief Remove value
62
+
63
+ @param[in] target set to process
64
+ @param[in] value value to remove
65
+ @return non-zero value on successful removal and zero value otherwise
66
+
67
+ This function removes and destroys (the first occurrence of) the element considered equal to the specified value.
68
+ The function returns zero value if `target` contains no such element.
69
+
70
+ @since 2.0
71
+ }
72
+ end
73
+ method(:int, :subset, { target: const_rvalue, other: const_rvalue }, constraint:-> { element.comparable? }).configure do
74
+ header %{
75
+ @brief Check if one set is a subset of another
76
+
77
+ @param[in] target set to compare
78
+ @param[in] other set to compare
79
+ @return non-zero value if `target` set is a subset of `other` set and zero value otherwise
80
+
81
+ @since 2.0
82
+ }
83
+ end
84
+ equal.configure do
85
+ code %{
86
+ assert(left);
87
+ assert(right);
88
+ return #{subset.(left, right)} && #{subset.(right, left)};
89
+ }
90
+ end
91
+ method(:int, :disjoint, { left: const_rvalue, right: const_rvalue }, constraint:-> { @set_operations && element.comparable? }).configure do
92
+ code %{
93
+ #{range} r;
94
+ #{element.const_lvalue} e;
95
+ assert(left);
96
+ assert(right);
97
+ for(r = #{range.new.(left)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
98
+ e = #{range.view_front.(:r)};
99
+ if(#{contains.(right, '*e')}) return 0;
100
+ }
101
+ for(r = #{range.new.(right)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
102
+ e = #{range.view_front.(:r)};
103
+ if(#{contains.(left, '*e')}) return 0;
104
+ }
105
+ return 1;
106
+ }
107
+ header %{
108
+ @brief Scan two sets for common elements
109
+
110
+ @param[in] left set to check
111
+ @param[in] right set to check
112
+ @return non-zero value if sets share no common elements and zero value otherwise
113
+
114
+ This function returns non-zero value if the specified sets are disjoint that is they share no common elements and zero value otherwise.
115
+
116
+ @since 2.0
117
+ }
118
+ end
119
+ method(:void, :join, { target: rvalue, source: const_rvalue }, constraint:-> { @set_operations && element.copyable? && element.comparable? }).configure do
120
+ code %{
121
+ #{range} r;
122
+ #{element.const_lvalue} e;
123
+ assert(target);
124
+ assert(source);
125
+ for(r = #{range.new.(source)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
126
+ e = #{range.view_front.(:r)};
127
+ #{put.(target, '*e')};
128
+ }
129
+ }
130
+ header %{
131
+ @brief Join sets
132
+
133
+ @param[in] target set to merge to
134
+ @param[in] source set to get elements from
135
+
136
+ This function copies all (new) elements from `source` set to `target` set.
137
+ This is effectively a set join operation _target | source -> target_.
138
+
139
+ @since 2.0
140
+ }
141
+ end
142
+ method(:void, :create_join, { target: lvalue, left: const_rvalue, right: const_rvalue }, constraint:-> { @set_operations && default_constructible? && element.copyable? && element.comparable? }).configure do
143
+ code %{
144
+ #{range} r;
145
+ #{element.const_lvalue} e;
146
+ assert(target);
147
+ assert(left);
148
+ assert(right);
149
+ #{default_create.(target)}; /* TODO create a set with specified capacity right away */
150
+ for(r = #{range.new.(left)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
151
+ e = #{range.view_front.(:r)};
152
+ #{put.(target, '*e')};
153
+ }
154
+ for(r = #{range.new.(right)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
155
+ e = #{range.view_front.(:r)};
156
+ #{put.(target, '*e')};
157
+ }
158
+ }
159
+ header %{
160
+ @brief Join sets into new set
161
+
162
+ @param[out] target set to merge set into
163
+ @param[in] left set to merge
164
+ @param[in] right set to merge
165
+
166
+ This function creates a new `target` set which contains copies of elements from both source sets.
167
+ This is effectively a set join operation _left | right -> target_.
168
+
169
+ @since 2.0
170
+ }
171
+ end
172
+ method(:void, :subtract, { target: rvalue, source: const_rvalue }, constraint:-> { @set_operations && element.copyable? && element.comparable? }).configure do
173
+ code %{
174
+ #{range} r;
175
+ #{element.const_lvalue} e;
176
+ assert(target);
177
+ assert(source);
178
+ for(r = #{range.new.(source)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
179
+ e = #{range.view_front.(:r)};
180
+ #{remove.(target, '*e')};
181
+ }
182
+ }
183
+ header %{
184
+ @brief Set substraction
185
+
186
+ @param[in] target set to subtract from
187
+ @param[in] source set to get elements for subtraction
188
+
189
+ This function removes all elements from `target` set which are contained in `source` set.
190
+ This is effectively a set subtraction operation _target \\ source -> target_.
191
+
192
+ @since 2.0
193
+ }
194
+ end
195
+ method(:void, :create_difference, { target: lvalue, left: const_rvalue, right: const_rvalue }, constraint:-> { @set_operations && default_constructible? && element.copyable? && element.comparable? }).configure do
196
+ code %{
197
+ #{range} r;
198
+ #{element.const_lvalue} e;
199
+ assert(target);
200
+ assert(left);
201
+ assert(right);
202
+ #{default_create.(target)};
203
+ for(r = #{range.new.(left)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
204
+ e = #{range.view_front.(:r)};
205
+ if(!#{contains.(right, '*e')}) #{put.(target, '*e')};
206
+ }
207
+ }
208
+ header %{
209
+ @brief Perform sets substraction into new set
210
+
211
+ @param[out] target set to contain difference
212
+ @param[in] left set to subtract from
213
+ @param[in] right set to subtract
214
+
215
+ This function creates new set and populates it with the copies of values from `left` set not contained in `right` set.
216
+ This is effectively a set subtraction operation _left \\ right -> target_.
217
+
218
+ @since 2.0
219
+ }
220
+ end
221
+ method(:void, :intersect, { target: rvalue, source: const_rvalue }, constraint:-> { @set_operations && element.copyable? && element.comparable? }).configure do
222
+ code %{
223
+ #{type} t;
224
+ assert(target);
225
+ assert(source);
226
+ #{copy.(:t, target)};
227
+ #{subtract.(:t, source)};
228
+ #{subtract.(target, :t)};
229
+ #{destroy.(:t)};
230
+ }
231
+ header %{
232
+ @brief Set intersection
233
+
234
+ @param[in] target set to retain elements
235
+ @param[in] source set to get elements for consideration
236
+
237
+ This function retains elements in `target` set which are also contained in `source` set.
238
+ This is effectively a set intersection operation _target & source -> target_.
239
+
240
+ @since 2.0
241
+ }
242
+ end
243
+ method(:void, :create_intersection, { target: lvalue, left: const_rvalue, right: const_rvalue }, constraint:-> { @set_operations && default_constructible? && element.copyable? && element.comparable? }).configure do
244
+ code %{
245
+ #{range} r;
246
+ #{element.const_lvalue} e;
247
+ assert(target);
248
+ assert(left);
249
+ assert(right);
250
+ #{default_create.(target)};
251
+ for(r = #{range.new.(left)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
252
+ e = #{range.view_front.(:r)};
253
+ if(#{contains.(right, '*e')}) #{put.(target, '*e')};
254
+ }
255
+ for(r = #{range.new.(right)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
256
+ e = #{range.view_front.(:r)};
257
+ if(#{contains.(left, '*e')}) #{put.(target, '*e')};
258
+ }
259
+ }
260
+ header %{
261
+ @brief Perform sets intersection into new set
262
+
263
+ @param[out] target set to contain intersection
264
+ @param[in] left set to get elements from
265
+ @param[in] right set to get elements from
266
+
267
+ This function creates a new set which contains copies of the elements shared by both source sets.
268
+ This is effectively a set intersection operation _left & right -> target_.
269
+
270
+ @since 2.0
271
+ }
272
+ end
273
+ method(:void, :disjoin, { target: rvalue, source: const_rvalue }, constraint:-> { @set_operations && element.copyable? && element.comparable? }).configure do
274
+ code %{
275
+ #{type} t;
276
+ assert(target);
277
+ assert(source);
278
+ #{copy.(:t, target)};
279
+ #{intersect.(:t, source)};
280
+ #{join.(target, source)};
281
+ #{subtract.(target, :t)};
282
+ #{destroy.(:t)};
283
+ }
284
+ header %{
285
+ @brief Set symmetric difference
286
+
287
+ @param[in] target set to retain elements
288
+ @param[in] source set to get elements for consideration
289
+
290
+ This function collects elements in `target` which are contained in either `target` set or `source` set, but not in both.
291
+ This is effectively a set symmetric difference operation _target ^ source -> target_.
292
+
293
+ @since 2.0
294
+ }
295
+ end
296
+ method(:void, :create_disjunction, { target: lvalue, left: const_rvalue, right: const_rvalue }, constraint:-> { @set_operations && default_constructible? && element.copyable? && element.comparable? }).configure do
297
+ code %{
298
+ #{range} r;
299
+ #{element.const_lvalue} e;
300
+ assert(target);
301
+ assert(left);
302
+ assert(right);
303
+ #{default_create.(target)};
304
+ for(r = #{range.new.(left)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
305
+ e = #{range.view_front.(:r)};
306
+ if(!#{contains.(right, '*e')}) #{put.(target, '*e')};
307
+ }
308
+ for(r = #{range.new.(right)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
309
+ e = #{range.view_front.(:r)};
310
+ if(!#{contains.(left, '*e')}) #{put.(target, '*e')};
311
+ }
312
+ }
313
+ header %{
314
+ @brief Perform symmetric sets difference into new set
315
+
316
+ @param[out] target set to contain difference
317
+ @param[in] left set to get elements from
318
+ @param[in] right set to get elements from
319
+
320
+ This function creates a new set which contains copies of elements which are contained in either `target` set or `source` set, but not in both.
321
+ This is effectively a set symmetric difference operation _left ^ right -> target_.
322
+
323
+ @since 2.0
324
+ }
325
+ end
326
+ end
327
+
328
+ end # Set
329
+
330
+
331
+ end
data/lib/autoc/std.rb ADDED
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'set'
5
+ require 'autoc/module'
6
+ require 'autoc/primitive'
7
+
8
+
9
+ # A collection of standard (mostly) primitive C types
10
+ module AutoC::STD
11
+
12
+
13
+ module PrimitiveCoercions
14
+ def to_type = Primitive.adopt(self)
15
+ def to_value = to_type.to_value
16
+ def lvalue = to_type.lvalue
17
+ def rvalue = to_type.rvalue
18
+ def const_lvalue = to_type.const_lvalue
19
+ def const_rvalue = to_type.const_rvalue
20
+ def ~@ = %{"#{self}"} # Return C side string literal
21
+ end
22
+
23
+ # Refinement handle automatic conversion o recognized C side types represented by string or symbol
24
+ module Coercions
25
+ refine ::Symbol do import_methods PrimitiveCoercions end
26
+ refine ::String do import_methods PrimitiveCoercions end
27
+ end
28
+
29
+
30
+ # Base class for a more elaborate primitive type directly includable into the module as a dependency
31
+ class Primitive < AutoC::Primitive
32
+
33
+ include AutoC::Entity
34
+
35
+ @@types = ::Set.new
36
+
37
+ def self.adopt(x)
38
+ @@types.each { |t| return t unless (t.matcher =~ x).nil? }
39
+ Primitive.new(x)
40
+ end
41
+
42
+ attr_reader :matcher
43
+
44
+ def initialize(type, matcher: Regexp.new("^#{type}$"), header: nil)
45
+ super(type)
46
+ @matcher = matcher
47
+ dependencies << header unless header.nil?
48
+ @@types << self
49
+ end
50
+
51
+ def to_value = rvalue
52
+
53
+ def rvalue = @rv ||= AutoC::Value.new(self)
54
+
55
+ def lvalue = @lv ||= AutoC::Value.new(self, reference: true)
56
+
57
+ def const_rvalue = @crv ||= AutoC::Value.new(self, constant: true)
58
+
59
+ def const_lvalue = @clv ||= AutoC::Value.new(self, constant: true, reference: true)
60
+
61
+ end
62
+
63
+
64
+ MATH_H = AutoC::SystemHeader.new 'math.h'
65
+ ASSERT_H = AutoC::SystemHeader.new 'assert.h'
66
+ STDDEF_H = AutoC::SystemHeader.new 'stddef.h'
67
+ MALLOC_H = AutoC::SystemHeader.new 'malloc.h'
68
+ STRING_H = AutoC::SystemHeader.new 'string.h'
69
+ STDBOOL_H = AutoC::SystemHeader.new 'stdbool.h'
70
+ COMPLEX_H = AutoC::SystemHeader.new 'complex.h'
71
+ INTTYPES_H = AutoC::SystemHeader.new 'inttypes.h'
72
+
73
+
74
+ # STDLIB_H = AutoC::SystemHeader.new 'stdlib.h'
75
+ # Required by Visual Studio's rand_s() to work
76
+ STDLIB_H = AutoC::Code.new interface: %{
77
+ #ifdef _MSC_VER
78
+ #define _CRT_RAND_S
79
+ #endif
80
+ #include <stdlib.h>
81
+ }
82
+
83
+ BOOL = Primitive.new '_Bool', matcher: /^(bool|_Bool)$/, header: STDBOOL_H
84
+
85
+
86
+ CHAR = Primitive.new 'char'
87
+ SIGNED_CHAR = Primitive.new 'signed char', matcher: /^signed\s+char$/
88
+ UNSIGNED_CHAR = Primitive.new 'unsigned char', matcher: /^unsigned\s+char$/
89
+
90
+
91
+ WCHAR_T = Primitive.new 'wchar_t', header: STDDEF_H
92
+
93
+
94
+ SHORT = SIGNED_SHORT = SHORT_INT = SIGNED_SHORT_INT = Primitive.new 'short', matcher: /^(signed\s+)?short(\s+int)?$/
95
+ UNSIGNED_SHORT = UNSIGNED_SHORT_INT = Primitive.new 'unsigned short', matcher: /^unsigned\s+short(\s+int)?$/
96
+
97
+
98
+ INT = SIGNED = SIGNED_INT = Primitive.new 'int', matcher: /^(int|signed|signed\s+int)$/
99
+ UNSIGNED = UNSIGNED_INT = Primitive.new 'unsigned', matcher: /^(unsigned|unsigned\s+int)$/
100
+
101
+
102
+ LONG = SIGNED_LONG = LONG_INT = SIGNED_LONG_INT = Primitive.new 'long', matcher: /^(signed\s+)?long(\s+int)?$/
103
+ UNSIGNED_LONG = UNSIGNED_LONG_INT = Primitive.new 'unsigned long', matcher: /^unsigned\s+long(\s+int)?$/
104
+
105
+
106
+ LONG_LONG = SIGNED_LONG_LONG = LONG_LONG_INT = SIGNED_LONG_LONG_INT = Primitive.new 'long long', matcher: /^(signed\s+)?long\s+long(\s+int)?$/
107
+ UNSIGNED_LONG_LONG = UNSIGNED_LONG_LONG_INT = Primitive.new 'unsigned long long', matcher: /^unsigned\s+long\s+long(\s+int)?$/
108
+
109
+
110
+ SIZE_T = Primitive.new 'size_t', header: STDDEF_H
111
+ PTRDIFF_T = Primitive.new 'ptrdiff_t', header: STDDEF_H
112
+ UINTPTR_T = Primitive.new 'uintptr_t', header: STDDEF_H
113
+
114
+
115
+ FLOAT = Primitive.new 'float'
116
+ DOUBLE = Primitive.new 'double'
117
+ LONG_DOUBLE = Primitive.new 'long double', matcher: /^long\s+double$/
118
+
119
+
120
+ FLOAT_T = Primitive.new 'float_t', header: MATH_H
121
+ DOUBLE_T = Primitive.new 'double_t', header: MATH_H
122
+
123
+
124
+ class Complex < Primitive
125
+ def hash_code = @hash_code ||= -> (target) { "((size_t)(crealf(#{target}))^(size_t)(cimagf(#{target})))" } # TODO use tgmath
126
+ end # Complex
127
+
128
+ COMPLEX = Complex.new '_Complex', matcher: /^(complex|_Complex)$/, header: COMPLEX_H
129
+ FLOAT_COMPLEX = Complex.new 'float _Complex', matcher: /^float\s+(complex|_Complex)$/, header: COMPLEX_H
130
+ DOUBLE_COMPLEX = Complex.new 'double _Complex', matcher: /^double\s+(complex|_Complex)$/, header: COMPLEX_H
131
+ LONG_DOUBLE_COMPLEX = Complex.new 'long double _Complex', matcher: /^long\s+double\s+(complex|_Complex)$/, header: COMPLEX_H
132
+
133
+
134
+ INTPTR_T = Primitive.new 'intptr_t', header: INTTYPES_H
135
+ INTMAX_T = Primitive.new 'intmax_t', header: INTTYPES_H
136
+ UINTMAX_T = Primitive.new 'uintmax_t', header: INTTYPES_H
137
+
138
+
139
+ [8, 16, 32, 64].each do |bit|
140
+ const_set((type = "int#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
141
+ const_set((type = "uint#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
142
+ const_set((type = "int_fast#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
143
+ const_set((type = "uint_fast#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
144
+ const_set((type = "int_least#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
145
+ const_set((type = "uint_least#{bit}_t").upcase, Primitive.new(type, header: INTTYPES_H))
146
+ end
147
+
148
+
149
+ end