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.
- checksums.yaml +5 -5
- data/CHANGES.md +3 -0
- data/README.md +149 -0
- data/cmake/AutoC.cmake +39 -0
- data/lib/autoc/allocators.rb +51 -0
- data/lib/autoc/association.rb +126 -0
- data/lib/autoc/box.rb +311 -0
- data/lib/autoc/cmake.rb +54 -0
- data/lib/autoc/collection.rb +83 -110
- data/lib/autoc/composite.rb +333 -0
- data/lib/autoc/cstring.rb +263 -0
- data/lib/autoc/function.rb +247 -0
- data/lib/autoc/hash_map.rb +328 -0
- data/lib/autoc/hash_set.rb +339 -0
- data/lib/autoc/hashers.rb +102 -0
- data/lib/autoc/list.rb +444 -0
- data/lib/autoc/module.rb +434 -0
- data/lib/autoc/openmp.rb +15 -0
- data/lib/autoc/primitive.rb +27 -0
- data/lib/autoc/ranges.rb +707 -0
- data/lib/autoc/record.rb +247 -0
- data/lib/autoc/scaffold/docs.rb +117 -0
- data/lib/autoc/scaffold/generic_value.rb +86 -0
- data/lib/autoc/scaffold/project.rb +75 -0
- data/lib/autoc/scaffold/test_cstring.rb +113 -0
- data/lib/autoc/scaffold/test_cstring_hash_set.rb +35 -0
- data/lib/autoc/scaffold/test_int_box.rb +22 -0
- data/lib/autoc/scaffold/test_int_hash_set.rb +448 -0
- data/lib/autoc/scaffold/test_int_list.rb +106 -0
- data/lib/autoc/scaffold/test_int_vector.rb +83 -0
- data/lib/autoc/scaffold/test_v2v_hash_map.rb +83 -0
- data/lib/autoc/scaffold/test_value_hash_set.rb +60 -0
- data/lib/autoc/scaffold/test_value_vector.rb +146 -0
- data/{test/test.rb → lib/autoc/scaffold/tests.rb} +179 -158
- data/lib/autoc/scaffold.rb +12 -0
- data/lib/autoc/sequential.rb +99 -0
- data/lib/autoc/set.rb +331 -0
- data/lib/autoc/std.rb +149 -0
- data/lib/autoc/type.rb +93 -531
- data/lib/autoc/vector.rb +290 -0
- data/lib/autoc.rb +4 -35
- metadata +55 -85
- data/.yardopts +0 -4
- data/CHANGES +0 -23
- data/README +0 -28
- data/doc/AutoC/Code.html +0 -523
- data/doc/AutoC/Collection.html +0 -1214
- data/doc/AutoC/HashMap.html +0 -1441
- data/doc/AutoC/HashSet.html +0 -916
- data/doc/AutoC/Iterators/Bidirectional.html +0 -204
- data/doc/AutoC/Iterators/Unidirectional.html +0 -200
- data/doc/AutoC/Iterators.html +0 -126
- data/doc/AutoC/List.html +0 -1039
- data/doc/AutoC/Maps.html +0 -290
- data/doc/AutoC/Module/File.html +0 -415
- data/doc/AutoC/Module/Header.html +0 -437
- data/doc/AutoC/Module/Source.html +0 -707
- data/doc/AutoC/Module.html +0 -948
- data/doc/AutoC/Priority.html +0 -138
- data/doc/AutoC/Queue.html +0 -1172
- data/doc/AutoC/Reference.html +0 -735
- data/doc/AutoC/Sets.html +0 -520
- data/doc/AutoC/String.html +0 -1394
- data/doc/AutoC/TreeMap.html +0 -1565
- data/doc/AutoC/TreeSet.html +0 -1447
- data/doc/AutoC/Type.html +0 -2148
- data/doc/AutoC/UserDefinedType.html +0 -1047
- data/doc/AutoC/Vector.html +0 -987
- data/doc/AutoC.html +0 -331
- data/doc/_index.html +0 -388
- data/doc/class_list.html +0 -51
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -58
- data/doc/css/style.css +0 -481
- data/doc/file.CHANGES.html +0 -117
- data/doc/file.README.html +0 -116
- data/doc/file_list.html +0 -61
- data/doc/frames.html +0 -17
- data/doc/index.html +0 -116
- data/doc/js/app.js +0 -243
- data/doc/js/full_list.js +0 -216
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -1307
- data/doc/top-level-namespace.html +0 -112
- data/lib/autoc/code.rb +0 -237
- data/lib/autoc/collection/hash_map.rb +0 -385
- data/lib/autoc/collection/hash_set.rb +0 -337
- data/lib/autoc/collection/iterator.rb +0 -39
- data/lib/autoc/collection/list.rb +0 -429
- data/lib/autoc/collection/map.rb +0 -41
- data/lib/autoc/collection/queue.rb +0 -517
- data/lib/autoc/collection/set.rb +0 -134
- data/lib/autoc/collection/tree_map.rb +0 -464
- data/lib/autoc/collection/tree_set.rb +0 -611
- data/lib/autoc/collection/vector.rb +0 -336
- data/lib/autoc/string.rb +0 -492
- data/test/test_auto.c +0 -7141
- data/test/test_auto.h +0 -753
- data/test/test_char_string.rb +0 -270
- data/test/test_int_list.rb +0 -35
- data/test/test_int_tree_set.rb +0 -111
- data/test/test_int_vector.rb +0 -34
- data/test/test_value_hash_map.rb +0 -162
- data/test/test_value_hash_set.rb +0 -173
- data/test/test_value_list.rb +0 -193
- data/test/test_value_queue.rb +0 -275
- data/test/test_value_tree_map.rb +0 -176
- data/test/test_value_tree_set.rb +0 -173
- data/test/test_value_vector.rb +0 -155
- data/test/value.rb +0 -80
data/lib/autoc/type.rb
CHANGED
@@ -1,555 +1,117 @@
|
|
1
|
-
|
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
|
-
# @
|
12
|
-
class
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
# @
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
92
|
-
|
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
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
163
|
-
|
164
|
-
|
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
|
-
|
260
|
-
|
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
|
-
|
266
|
-
|
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
|
-
|
269
|
-
|
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
|
-
|
272
|
-
|
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
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
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}(<,&rt)
|
526
|
-
#define _#{less}(lt,rt) #{less}(<,&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
|