autoc 1.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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