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/type.rb CHANGED
@@ -1,555 +1,117 @@
1
- require "forwardable"
2
- require "autoc/code"
1
+ # frozen_string_literal: true
3
2
 
4
3
 
5
4
  module AutoC
6
-
7
5
 
8
- # @private
9
- class Dispatcher
10
6
 
11
- # @private
12
- class ParameterArray < Array
13
- def self.coerce(*params)
14
- out = []
15
- i = 0
16
- params.each do |t|
17
- i += 1
18
- out << (t.is_a?(Array) ? t.collect {|x| x.to_s} : [t.to_s, "_#{i}"])
19
- end
20
- self.new(out)
21
- end
22
- # Test for parameter list compatibility
23
- def ===(other) other.is_a?(ParameterArray) && types == other.types end
24
- def types; collect {|x| x.first} end
25
- def names; collect {|x| x.last} end
26
- def pass; names.join(",") end
27
- # ANSI C instructs the empty parameter list to be marked as `void`
28
- def declaration; empty? ? :void : types.join(",") end
29
- def definition; empty? ? :void : collect {|x| "#{x.first} #{x.last}"}.join(",") end
30
- end # ParameterArray
7
+ # @abstract
8
+ class Type
9
+
10
+ # C side type signature
11
+ attr_reader :signature
12
+
13
+ def self.abstract(method) = remove_method(method)
14
+
15
+ def initialize(signature) = @signature = signature.to_s
31
16
 
32
- # def call(*params)
33
-
34
- def dispatch(*params)
35
- if params.empty?
36
- self
37
- else
38
- params = [] if params.size == 1 && params.first.nil?
39
- call(*params)
40
- end
41
- end
42
-
43
- end # Dispatcher
17
+ def to_type = self
44
18
 
19
+ def to_s = signature
45
20
 
46
- # @private
47
- class Statement < Dispatcher
48
-
49
- attr_reader :parameters
50
-
51
- def initialize(params = [])
52
- @parameters = ParameterArray.coerce(*params)
53
- end
54
-
55
- end # Statement
21
+ def inspect = "#{signature} <#{self.class}>"
56
22
 
23
+ # def lvalue()
24
+ # def rvalue()
25
+ # def const_lvalue()
26
+ # def const_rvalue()
57
27
 
58
- # @private
59
- class Function < Dispatcher
60
-
61
- # @private
62
- class Signature
28
+ # @abstract
29
+ # Synthesize the source side code to create an instance in place of the +value+ and perform its default
30
+ # initialization (the default constructor).
31
+ #
32
+ # Original contents of the +value+ is overwritten.
33
+ #
34
+ # @param value [String | Symbol] source side storage designation where the instance is to be created
35
+ # @return [String] source side code snippet
36
+ abstract def default_create(value) = ABSTRACT
63
37
 
64
- attr_reader :parameters, :result
38
+ # @abstract
39
+ # Synthesize the source side code to create an instance in place of the +value+ and and initialize it with
40
+ # supplied +args+ (the custom constructor).
41
+ #
42
+ # The +args+ elements are expected to be of the {Type} type.
43
+ #
44
+ # Original contents of the +value+ is overwritten.
45
+ #
46
+ # @param value [String | Symbol] source side storage designation where the instance is to be created
47
+ # @param args [Array] list of types to be supplied to the constructor
48
+ # @return [String] source side code snippet
49
+ abstract def custom_create(value, *args) = ABSTRACT
65
50
 
66
- def initialize(params = [], result = nil)
67
- @parameters = Dispatcher::ParameterArray.coerce(*params)
68
- @result = (result.nil? ? :void : result).to_s
69
- end
51
+ # @abstract
52
+ # Synthesize the source side code to destroy the instance in place of the +value+ (the destructor).
53
+ #
54
+ # @param value [String | Symbol] source side storage designation for the instance to be destroyed
55
+ # @return [String] source side code snippet
56
+ abstract def destroy(value) = ABSTRACT
70
57
 
71
- end # Signature
58
+ # @abstract
59
+ # Synthesize the source side code to create an instance in place of the +value+ initializing it with a contents of
60
+ # the +origin+ instance (the copy constructor).
61
+ #
62
+ # Original contents of the +value+ is overwritten.
63
+ # The contents of the +source+ is left intact.
64
+ #
65
+ # @param value [String | Symbol] source side storage designation where the instance is to be created
66
+ # @param source [String | Symbol] source side storage designation taken as the origin for the copying operation
67
+ # @return [String] source side code snippet
68
+ abstract def copy(value, source) = ABSTRACT
72
69
 
73
- extend Forwardable
74
-
75
- def_delegators :@signature,
76
- :parameters, :result
77
-
78
- attr_reader :name, :signature
79
-
80
- def initialize(name, a = [], b = nil)
81
- @name = AutoC.c_id(name)
82
- @signature = a.is_a?(Signature) ? a : Signature.new(a, b)
83
- end
84
-
85
- def to_s; name end
86
-
87
- def call(*params)
88
- "#{name}(#{params.join(',')})"
89
- end
70
+ # @abstract TODO
71
+ abstract def equal(value, other) = ABSTRACT
90
72
 
91
- def definition
92
- "#{result} #{name}(#{parameters.definition})"
93
- end
94
-
95
- def declaration
96
- "#{result} #{name}(#{parameters.declaration})"
97
- end
98
-
99
- end # Function
73
+ # @abstract TODO
74
+ abstract def compare(value, other) = ABSTRACT
100
75
 
76
+ # @abstract TODO
77
+ abstract def hash_code(value) = ABSTRACT
101
78
 
102
- class Type < Code
103
-
104
- # @private
105
- CommonCode = Class.new(Code) do
106
- def write_intf(stream)
107
- stream << %$
108
- #ifndef AUTOC_INLINE
109
- #if defined(_MSC_VER) || defined(__DMC__)
110
- #define AUTOC_INLINE AUTOC_STATIC __inline
111
- #elif defined(__LCC__)
112
- #define AUTOC_INLINE AUTOC_STATIC /* LCC rejects static __inline */
113
- #elif __STDC_VERSION__ >= 199901L
114
- #define AUTOC_INLINE AUTOC_STATIC inline
115
- #else
116
- #define AUTOC_INLINE AUTOC_STATIC
117
- #endif
118
- #endif
119
- #ifndef AUTOC_EXTERN
120
- #ifdef __cplusplus
121
- #define AUTOC_EXTERN extern "C"
122
- #else
123
- #define AUTOC_EXTERN extern
124
- #endif
125
- #endif
126
- #ifndef AUTOC_STATIC
127
- #if defined(_MSC_VER)
128
- #define AUTOC_STATIC __pragma(warning(suppress:4100)) static
129
- #elif defined(__GNUC__)
130
- #define AUTOC_STATIC __attribute__((__used__)) static
131
- #else
132
- #define AUTOC_STATIC static
133
- #endif
134
- #endif
135
- #include <stddef.h>
136
- #include <stdlib.h>
137
- #include <assert.h>
138
- $
139
- end
140
- def write_decls(stream)
141
- stream << %$
142
- #include <limits.h>
143
- #define AUTOC_MIN(a,b) ((a) > (b) ? (b) : (a))
144
- #define AUTOC_MAX(a,b) ((a) > (b) ? (a) : (b))
145
- #define AUTOC_RCYCLE(x) (((x) << 1) | ((x) >> (sizeof(x)*CHAR_BIT - 1))) /* NOTE : valid for unsigned types only */
146
- $
147
- end
148
- end.new
79
+ # @abstract TODO replace value with a copy of source destroying prevous contents
80
+ # abstract def replace(value, source) = nil
149
81
 
150
- def self.coerce(type)
151
- type.is_a?(Type) ? type : UserDefinedType.new(type)
152
- end
153
-
154
- def hash; self.class.hash ^ type.hash end
155
-
156
- def ==(other) self.class == other.class && type == other.type end
157
-
158
- alias :eql? :==
159
-
160
- def entities; super << CommonCode end
82
+ # Test whether the type has a default (parameterless) constructor.
83
+ # This implementation looks up the {#default_create} method.
84
+ def default_constructible? = respond_to?(:default_create)
161
85
 
162
- attr_reader :type, :type_ref
163
-
164
- def prefix
165
- # Lazy evaluator for simple types like char* which do not actually use
166
- # this method and hence do not require the prefix to be a valid C identifier
167
- AutoC.c_id(type)
168
- end
169
-
170
- def initialize(type, visibility = :public)
171
- @type = type.to_s
172
- @type_ref = "#{self.type}*"
173
- @visibility = [:public, :private, :static].include?(visibility) ? visibility : raise("unsupported visibility")
174
- # Canonic special method signatures
175
- @signature = {
176
- :ctor => Function::Signature.new([type^:self]),
177
- :dtor => Function::Signature.new([type^:self]),
178
- :copy => Function::Signature.new([type^:dst, type^:src]),
179
- :equal => Function::Signature.new([type^:lt, type^:rt], :int),
180
- :identify => Function::Signature.new([type^:self], :size_t),
181
- :less => Function::Signature.new([type^:lt, type^:rt], :int),
182
- }
183
- end
184
-
185
- def method_missing(method, *args)
186
- str = method.to_s
187
- str = str.sub(/[\!\?]$/, '') # Strip trailing ? or !
188
- x = false # Have leading underscore
189
- if /_(.*)/ =~ str
190
- str = $1
191
- x = true
192
- end
193
- fn = prefix + str[0,1].capitalize + str[1..-1] # Ruby 1.8 compatible
194
- fn = "_" << fn if x # Carry over the leading underscore
195
- if args.empty?
196
- fn # Emit bare function name
197
- elsif args.size == 1 && args.first == nil
198
- fn + '()' # Use sole nil argument to emit function call with no arguments
199
- else
200
- fn + '(' + args.join(',') + ')' # Emit normal function call with supplied arguments
201
- end
202
- end
203
-
204
- def write_intf(stream)
205
- if public?
206
- write_intf_types(stream)
207
- write_intf_decls(stream, extern, inline)
208
- end
209
- end
210
-
211
- def write_decls(stream)
212
- if private?
213
- write_intf_types(stream)
214
- write_intf_decls(stream, extern, inline)
215
- elsif static?
216
- write_intf_types(stream)
217
- write_intf_decls(stream, static, inline)
218
- end
219
- end
220
-
221
- def write_defs(stream)
222
- if public? || private?
223
- write_impls(stream, nil)
224
- elsif static?
225
- write_impls(stream, static)
226
- end
227
- end
228
-
229
- # Abstract methods which must be defined in descendant classes
230
-
231
- # def write_intf_types(stream)
232
-
233
- # def write_intf_decls(stream, declare, define)
234
-
235
- # def write_impls(stream, define)
236
-
237
- def extern; :AUTOC_EXTERN end
238
-
239
- def inline; :AUTOC_INLINE end
240
-
241
- def static; :AUTOC_STATIC end
242
-
243
- def assert; :assert end
244
-
245
- def malloc; :malloc end
246
-
247
- def calloc; :calloc end
248
-
249
- def free; :free end
250
-
251
- def abort; :abort end
252
-
253
- def public?; @visibility == :public end
254
-
255
- def private?; @visibility == :private end
256
-
257
- def static?; @visibility == :static end
86
+ # Test whether the type has a custom constructor which accepts a number of parameters.
87
+ # This implementation looks up the {#custom_create} method.
88
+ def custom_constructible? = respond_to?(:custom_create)
258
89
 
259
- # A generic type is not required to provide any special functions therefore all the
260
- # availability methods below return false
261
-
262
- # Returns *true* if the type provides a well-defined parameterless default type constructor
263
- def constructible?; false end
90
+ # Test whether the type can be constructed, with either default or parametrized initialization.
91
+ # This implementation queries {#custom_constructible?} and {#default_constructible?}.
92
+ def constructible? = custom_constructible? || default_constructible?
264
93
 
265
- # Returns *true* if the type provides a well-defined type constructor which can have extra arguments
266
- def initializable?; false end
94
+ # Test whether the type has a non-trivial destructor.
95
+ # This implementation looks up the {#destroy} method.
96
+ def destructible? = respond_to?(:destroy)
267
97
 
268
- # Returns *true* if the type provides a well-defined type destructor
269
- def destructible?; false end
98
+ # Test whether the type can be created from an instance of the same type (cloned).
99
+ # This implementation looks up the {#copy} method.
100
+ def copyable? = respond_to?(:copy)
270
101
 
271
- # Returns *true* if the type provides a well-defined copy constructor to create a clone of an instance
272
- def copyable?; false end
102
+ # Test whether the type has a well-defined test for content equality against another value of the same type.
103
+ # This implementation looks up the {#equal} method.
104
+ def comparable? = respond_to?(:equal)
273
105
 
274
- # Returns *true* if the type provides a well-defined equality test function
275
- def comparable?; false end
276
-
277
- # Returns *true* if the type provides a well-defined 'less than' test function
278
- def orderable?; false end
279
-
280
- # Returns *true* if the type provides corrset soritng routines
281
- def sortable?; comparable? && orderable? end
282
-
283
- # Returns *true* if the type provides a well-defined hash calculation function
284
- def hashable?; false end
285
-
286
- # Create forwarding readers which take arbitrary number of arguments
287
- [:ctor, :dtor, :copy, :equal, :identify, :less].each do |name|
288
- class_eval %$
289
- def #{name}(*args)
290
- @#{name}.dispatch(*args)
291
- end
292
- $
293
- end
294
-
295
- end # Type
296
-
297
-
298
- =begin
299
-
300
- UserDefinedType represents a user-defined custom type.
301
-
302
- =end
303
- class UserDefinedType < Type
304
-
305
- # @private
306
- class PublicDeclaration < Code
307
- def entities; super << Type::CommonCode end
308
- def initialize(forward) @forward = forward.to_s end
309
- def hash; @forward.hash end
310
- def ==(other) self.class == other.class && @forward == other.instance_variable_get(:@forward) end
311
- alias :eql? :==
312
- def write_intf(stream)
313
- stream << "\n#{@forward}\n"
314
- end
315
- end # PublicDeclaration
316
-
317
- def entities; super.concat(@deps) end
318
-
319
- def prefix; @prefix.nil? ? super : @prefix end
320
-
321
- def initialize(opt)
322
- opt = {:type => opt} if opt.is_a?(::Symbol) || opt.is_a?(::String)
323
- if opt.is_a?(Hash)
324
- t = opt[:type].nil? ? raise("type is not specified") : opt[:type].to_s
325
- else
326
- raise "argument must be a Symbol, String or Hash"
327
- end
328
- super(t)
329
- @prefix = AutoC.c_id(opt[:prefix]) unless opt[:prefix].nil?
330
- @deps = []; @deps << PublicDeclaration.new(opt[:forward]) unless opt[:forward].nil?
331
- define_callable(:ctor, opt) {def call(obj) "((#{obj}) = 0)" end}
332
- define_callable(:dtor, opt) {def call(obj) end}
333
- define_callable(:copy, opt) {def call(dst, src) "((#{dst}) = (#{src}))" end}
334
- define_callable(:equal, opt) {def call(lt, rt) "((#{lt}) == (#{rt}))" end}
335
- define_callable(:less, opt) {def call(lt, rt) "((#{lt}) < (#{rt}))" end}
336
- define_callable(:identify, opt) {def call(obj) "((size_t)(#{obj}))" end}
337
- end
338
-
339
- def constructible?; !@ctor.nil? && @ctor.parameters.size == 1 end
340
-
341
- def initializable?; !@ctor.nil? end
342
-
343
- def destructible?; !@dtor.nil? end
344
-
345
- def copyable?; !@copy.nil? end
346
-
347
- def comparable?; !@equal.nil? end
348
-
349
- def orderable?; !@less.nil? end
350
-
351
- def hashable?; !@identify.nil? end
352
-
353
- # The methods below are left empty as the user-defined types have no implementation on their own
354
-
355
- def write_intf_types(stream) end
356
-
357
- def write_intf_decls(stream, declare, define) end
358
-
359
- def write_impls(stream, define) end
360
-
361
- private
362
-
363
- # Default methods creator
364
- def define_callable(name, opt, &code)
365
- c = if opt.has_key?(name) && opt[name].nil?
366
- nil # Disable specific capability by explicitly setting the key to nil
367
- else
368
- signature = @signature[name]
369
- c = if opt[name].nil?
370
- # Implicit nil as returned by Hash#default method does synthesize statement block with default (canonic) parameter list
371
- Class.new(Statement, &code).new(signature.parameters)
372
- elsif opt[name].is_a?(Function)
373
- opt[name] # If a Function instance is given, pass it through
374
- else
375
- # If only a name is specified, assume it is the function name with default signature
376
- Function.new(opt[name], signature)
377
- end
378
- end
379
- instance_variable_set("@#{name}", c)
380
- end
381
-
382
- end # UserDefinedType
383
-
384
-
385
- =begin
386
-
387
- Reference represents a managed counted reference for any type.
388
- It can be used with any type, including AutoC collections themselves.
389
-
390
- == Generated C interface
391
-
392
- === Type management
393
-
394
- [cols="2*"]
395
- |===
396
- |*_Type_* * ~type~New(...)
397
- |
398
- Create and return a reference to *_Type_* with reference count set to one.
399
-
400
- The storage for the returned instance is malloc()'ed. The instance is constructed with the type's constructor ~type~Ctor(...).
401
-
402
- NOTE: The generated method borrows the second and subsequent arguments from the respective constructor.
403
-
404
- |*_Type_* * ~type~Ref(*_Type_* * self)
405
- |
406
- Increment the +self+'s reference count and return +self+.
407
-
408
- |*_void_* ~type~Free(*_Type_* * self)
409
- |
410
- Decrement the +self+'s reference count.
411
- If the reference count reaches zero, free the storage and destroy the instance with the type's destructor ~type~Dtor().
412
-
413
- =end
414
- class Reference < Type
415
-
416
- extend Forwardable
417
-
418
- def_delegators :@target,
419
- :prefix,
420
- :public?, :private?, :static?,
421
- :constructible?, :initializable?, :destructible?, :comparable?, :orderable?, :hashable?
422
-
423
- # Return *true* since reference copying involves no call to the underlying type's copy constructor
424
- def copyable?; true end
425
-
426
- attr_reader :target
427
-
428
- def initialize(target)
429
- @target = Type.coerce(target)
430
- super(@target.type_ref) # NOTE : the type of the Reference instance itself is actually a pointer type
431
- @init = Dispatcher::ParameterArray.new(@target.ctor.parameters[1..-1]) # Capture extra parameters from the target type constructor
432
- define_callable(:ctor, @init) {def call(obj, *params) "((#{obj}) = #{@ref.new?}(#{params.join(',')}))" end}
433
- define_callable(:dtor, [type]) {def call(obj) "#{@ref.free?}(#{obj})" end}
434
- define_callable(:copy, [type, type]) {def call(dst, src) "((#{dst}) = #{@ref.ref?}(#{src}))" end}
435
- define_callable(:equal, [type, type]) {def call(lt, rt) @target.equal("*#{lt}", "*#{rt}") end}
436
- define_callable(:less, [type, type]) {def call(lt, rt) @target.less("*#{lt}", "*#{rt}") end}
437
- define_callable(:identify, [type]) {def call(obj) @target.identify("*#{obj}") end}
438
- end
439
-
440
- def ==(other) @target == other.instance_variable_get(:@target) end
441
-
442
- alias :eql? :==
443
-
444
- def entities; super << @target end
445
-
446
- def write_intf_decls(stream, declare, define)
447
- stream << %$
448
- /***
449
- **** <#{type}> (#{self.class})
450
- ***/
451
- #{declare} #{type} #{new?}(#{@init.declaration});
452
- #{declare} #{type} #{ref?}(#{type});
453
- #{declare} void #{free?}(#{type});
454
- $
455
- end
456
-
457
- def write_impls(stream, define)
458
- stream << %$
459
- #define AUTOC_COUNTER(p) (*(size_t*)((char*)(p) + sizeof(#{@target.type})))
460
- #{define} #{type} #{new?}(#{@init.definition}) {
461
- #{type} self = (#{type})#{malloc}(sizeof(#{@target.type}) + sizeof(size_t)); #{assert}(self);
462
- #{@target.ctor("*self", *@init.names)};
463
- AUTOC_COUNTER(self) = 1;
464
- return self;
465
- }
466
- #{define} #{type} #{ref?}(#{type} self) {
467
- #{assert}(self);
468
- ++AUTOC_COUNTER(self);
469
- return self;
470
- }
471
- #{define} void #{free?}(#{type} self) {
472
- #{assert}(self);
473
- if(--AUTOC_COUNTER(self) == 0) {
474
- #{@target.dtor("*self")};
475
- #{free}(self);
476
- }
477
- }
478
- #undef AUTOC_COUNTER
479
- $
480
- end
481
-
482
- private
483
-
484
- # @private
485
- class BoundStatement < Statement
486
- def initialize(ref, target, params)
487
- super(params)
488
- @ref = ref
489
- @target = target
490
- end
491
- end # BoundStatement
492
-
493
- def define_callable(name, param_types, &code)
494
- instance_variable_set("@#{name}", Class.new(BoundStatement, &code).new(self, @target, param_types))
495
- end
496
-
497
- end # Reference
498
-
499
-
500
- # @private
501
- module Type::Redirecting
502
-
503
- # Setup special methods which receive types by reference instead of by value
504
- def initialize_redirectors
505
- define_redirector(:ctor, Function::Signature.new([type_ref^:self]))
506
- define_redirector(:dtor, Function::Signature.new([type_ref^:self]))
507
- define_redirector(:copy, Function::Signature.new([type_ref^:dst, type_ref^:src]))
508
- define_redirector(:equal, Function::Signature.new([type_ref^:lt, type_ref^:rt], :int))
509
- define_redirector(:identify, Function::Signature.new([type_ref^:self], :size_t))
510
- define_redirector(:less, Function::Signature.new([type_ref^:lt, type_ref^:rt], :int))
511
- end
512
-
513
- def write_redirectors(stream, declare, define)
514
- # Emit default redirection macros
515
- # Unlike other special methods the constructors may have extra arguments
516
- # Assume the constructor's first parameter is always a target
517
- ctor_ex = ctor.parameters.names[1..-1]
518
- ctor_lt = ["self"].concat(ctor_ex).join(',')
519
- ctor_rt = ["&self"].concat(ctor_ex).join(',')
520
- stream << %$
521
- #define _#{ctor}(#{ctor_lt}) #{ctor}(#{ctor_rt})
522
- #define _#{dtor}(self) #{dtor}(&self)
523
- #define _#{identify}(self) #{identify}(&self)
524
- #define _#{copy}(dst,src) #{copy}(&dst,&src)
525
- #define _#{equal}(lt,rt) #{equal}(&lt,&rt)
526
- #define _#{less}(lt,rt) #{less}(&lt,&rt)
527
- $
528
- end
529
-
530
- private
531
-
532
- # @private
533
- class Redirector < Function
534
- # Redirect call to the specific macro
535
- def call(*params) "_#{name}(" + params.join(',') + ')' end
536
- end # Redirector
537
-
538
- def define_redirector(name, signature)
539
- instance_variable_set("@#{name}", Redirector.new(method_missing(name), signature))
540
- end
541
-
542
- end # Redirecting
543
-
544
-
545
- # Class adjustments for the function signature definition DSL
546
- [::Symbol, ::String, Type].each do |type|
547
- type.class_eval do
548
- def ^(name)
549
- [self, name]
550
- end
551
- end
552
- end
553
-
554
-
555
- end # AutoC
106
+ # Test whether the type can be compared for less-equal-more against another value of the same type.
107
+ # Orderable type's values can be sorted and put into tree-based containers.
108
+ # For the type to be comparable this implementation looks up the {#compare} method.
109
+ def orderable? = respond_to?(:compare)
110
+
111
+ # Test whether the type's values which can be the elements of hash-based containers.
112
+ def hashable? = comparable? && respond_to?(:hash_code)
113
+
114
+ end # Type
115
+
116
+
117
+ end