autoc 0.8 → 1.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/README +15 -4
  3. data/doc/AutoC.html +245 -0
  4. data/doc/AutoC/Code.html +520 -0
  5. data/doc/AutoC/Collection.html +923 -0
  6. data/doc/AutoC/HashMap.html +1161 -0
  7. data/doc/AutoC/HashSet.html +1122 -0
  8. data/doc/AutoC/List.html +1002 -0
  9. data/doc/AutoC/Module.html +951 -0
  10. data/doc/AutoC/Module/File.html +412 -0
  11. data/doc/AutoC/Module/Header.html +432 -0
  12. data/doc/AutoC/Module/Source.html +704 -0
  13. data/doc/AutoC/Priority.html +138 -0
  14. data/doc/AutoC/Queue.html +1167 -0
  15. data/doc/AutoC/Type.html +1152 -0
  16. data/doc/AutoC/UserDefinedType.html +655 -0
  17. data/doc/AutoC/Vector.html +856 -0
  18. data/doc/_index.html +299 -0
  19. data/doc/class_list.html +54 -0
  20. data/doc/css/common.css +1 -0
  21. data/doc/css/full_list.css +57 -0
  22. data/doc/css/style.css +339 -0
  23. data/doc/file.README.html +112 -0
  24. data/doc/file_list.html +56 -0
  25. data/doc/frames.html +26 -0
  26. data/doc/index.html +112 -0
  27. data/doc/js/app.js +219 -0
  28. data/doc/js/full_list.js +178 -0
  29. data/doc/js/jquery.js +4 -0
  30. data/doc/method_list.html +605 -0
  31. data/doc/top-level-namespace.html +112 -0
  32. data/lib/autoc.rb +35 -12
  33. data/lib/autoc/{code_builder.rb → code.rb} +230 -247
  34. data/lib/autoc/collection.rb +137 -0
  35. data/lib/autoc/collection/hash_map.rb +388 -0
  36. data/lib/autoc/collection/hash_set.rb +433 -0
  37. data/lib/autoc/collection/list.rb +410 -0
  38. data/lib/autoc/collection/queue.rb +514 -0
  39. data/lib/autoc/collection/vector.rb +295 -0
  40. data/lib/autoc/type.rb +198 -0
  41. data/test/test.c +921 -396
  42. data/test/test.h +41 -0
  43. data/test/test.rb +21 -26
  44. data/test/test_auto.c +2630 -3961
  45. data/test/test_auto.h +449 -560
  46. metadata +50 -17
  47. data/lib/autoc/data_struct_builder.rb +0 -1794
  48. data/lib/autoc/type_builder.rb +0 -24
  49. data/manual/manual.pdf +0 -0
metadata CHANGED
@@ -1,31 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoc
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.8'
5
- prerelease:
4
+ version: '1.0'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Oleg A. Khlybov
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-05 00:00:00.000000000 Z
11
+ date: 2014-06-06 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description: ! " AutoC is a collection of Ruby modules related to automatic C source
15
- code generation.\n * CodeBuilder -- multi-file C module generator.\n * DataStructBuilder
16
- -- generators of strongly-typed data containers similar to the C++'s standard generic
17
- containers.\n"
13
+ description: |2
14
+ AutoC is a collection of Ruby modules related to automatic C source code generation:
15
+ 1) Multi-file C module generator.
16
+ 2) Generators for strongly-typed generic collections similar to those from the C++ standard template library.
18
17
  email: fougas@mail.ru
19
18
  executables: []
20
19
  extensions: []
21
20
  extra_rdoc_files: []
22
21
  files:
23
- - lib/autoc/code_builder.rb
24
- - lib/autoc/data_struct_builder.rb
25
- - lib/autoc/type_builder.rb
22
+ - lib/autoc/code.rb
23
+ - lib/autoc/collection/hash_map.rb
24
+ - lib/autoc/collection/hash_set.rb
25
+ - lib/autoc/collection/list.rb
26
+ - lib/autoc/collection/queue.rb
27
+ - lib/autoc/collection/vector.rb
28
+ - lib/autoc/collection.rb
29
+ - lib/autoc/type.rb
26
30
  - lib/autoc.rb
27
- - manual/manual.pdf
31
+ - doc/AutoC/Code.html
32
+ - doc/AutoC/Collection.html
33
+ - doc/AutoC/HashMap.html
34
+ - doc/AutoC/HashSet.html
35
+ - doc/AutoC/List.html
36
+ - doc/AutoC/Module/File.html
37
+ - doc/AutoC/Module/Header.html
38
+ - doc/AutoC/Module/Source.html
39
+ - doc/AutoC/Module.html
40
+ - doc/AutoC/Priority.html
41
+ - doc/AutoC/Queue.html
42
+ - doc/AutoC/Type.html
43
+ - doc/AutoC/UserDefinedType.html
44
+ - doc/AutoC/Vector.html
45
+ - doc/AutoC.html
46
+ - doc/class_list.html
47
+ - doc/css/common.css
48
+ - doc/css/full_list.css
49
+ - doc/css/style.css
50
+ - doc/file.README.html
51
+ - doc/file_list.html
52
+ - doc/frames.html
53
+ - doc/index.html
54
+ - doc/js/app.js
55
+ - doc/js/full_list.js
56
+ - doc/js/jquery.js
57
+ - doc/method_list.html
58
+ - doc/top-level-namespace.html
59
+ - doc/_index.html
28
60
  - test/test.c
61
+ - test/test.h
29
62
  - test/test.rb
30
63
  - test/test_auto.c
31
64
  - test/test_auto.h
@@ -33,26 +66,26 @@ files:
33
66
  homepage: http://autoc.sourceforge.net/
34
67
  licenses:
35
68
  - BSD
69
+ metadata: {}
36
70
  post_install_message:
37
71
  rdoc_options: []
38
72
  require_paths:
39
73
  - lib
40
74
  required_ruby_version: !ruby/object:Gem::Requirement
41
- none: false
42
75
  requirements:
43
- - - ! '>='
76
+ - - '>='
44
77
  - !ruby/object:Gem::Version
45
78
  version: '1.8'
46
79
  required_rubygems_version: !ruby/object:Gem::Requirement
47
- none: false
48
80
  requirements:
49
- - - ! '>='
81
+ - - '>='
50
82
  - !ruby/object:Gem::Version
51
83
  version: '0'
52
84
  requirements: []
53
85
  rubyforge_project:
54
- rubygems_version: 1.8.24
86
+ rubygems_version: 2.0.14
55
87
  signing_key:
56
- specification_version: 3
88
+ specification_version: 4
57
89
  summary: A host of Ruby modules related to automatic C source code generation
58
90
  test_files: []
91
+ has_rdoc:
@@ -1,1794 +0,0 @@
1
- require "set"
2
- require "autoc/code_builder"
3
-
4
-
5
- =begin rdoc
6
- Generators for strongly-typed C data containers similar to C++ STL container classes.
7
-
8
- The data types used as elements for generated containers may be of almost arbitrary type,
9
- with either value or reference semantics. A data type may be supplied with a host of user-defined functions
10
- performing specific operations such as cloning, destruction and a like on it.
11
- If no such function is specified, a default operation is generated.
12
-
13
- A data structure generator with name <code>type</code> creates a C struct named <code>type</code> and a host of functions named <code>type*()</code>.
14
- From now on, the following convention is applied:
15
- when referring to a generated C function the container name portion of a function is abbreviated by the hash sign <code>#</code>, for example, the full method
16
- <code>BlackBoxPut()</code> of a data container <code>BlackBox</code> will be abbreviated as <code>#Put()</code>.
17
-
18
- Some notes on generated data structures:
19
-
20
- * Use proper pair of construction and destruction functions: those containers created on stack with <code>#Ctor()</code>
21
- must be destroyed with <code>#Dtor()</code> while those created on heap with <code>#New()</code> must be destroyed with <code>#Destroy()</code>.
22
- =end
23
- module DataStructBuilder
24
-
25
-
26
- # :nodoc:
27
- PrologueCode = Class.new(CodeBuilder::Code) do
28
- def write_intf(stream)
29
- stream << %$
30
- #include <stddef.h>
31
- #include <stdlib.h>
32
- #include <malloc.h>
33
- #include <assert.h>
34
- #ifndef __DATA_STRUCT_INLINE
35
- #if defined(_MSC_VER) || defined(__PGI)
36
- #define __DATA_STRUCT_INLINE __inline static
37
- #elif __STDC_VERSION__ >= 199901L && !defined(__DMC__)
38
- #define __DATA_STRUCT_INLINE inline static
39
- #else
40
- #define __DATA_STRUCT_INLINE static
41
- #endif
42
- #endif
43
- #ifndef __DATA_STRUCT_EXTERN
44
- #if defined(__cplusplus)
45
- #define __DATA_STRUCT_EXTERN extern "C"
46
- #else
47
- #define __DATA_STRUCT_EXTERN extern
48
- #endif
49
- #endif
50
- $
51
- stream << %$
52
- #include <stdio.h>
53
- $ if $debug
54
- end
55
- end.new # PrologueCode
56
-
57
-
58
- =begin rdoc
59
- Base class for all C data container generators.
60
- =end
61
- class Code < CodeBuilder::Code
62
- undef abort;
63
- @@overrides = {:malloc=>"malloc", :calloc=>"calloc", :free=>"free", :assert=>"assert", :abort=>"abort", :extern=>"__DATA_STRUCT_EXTERN", :static=>"static", :inline=>"__DATA_STRUCT_INLINE"}
64
- # String-like prefix for generated data type. Must be a valid C identifier.
65
- attr_reader :type
66
- # Setups the data structure generator.
67
- # +type+ is a C type name used as a prefix for generated container functions. It must be a valid C identifier.
68
- def initialize(type)
69
- @type = type.to_s # TODO validate
70
- end
71
- protected
72
- # :nodoc:
73
- def method_missing(method, *args)
74
- if @@overrides.include?(method)
75
- @@overrides[method]
76
- else
77
- s = method.to_s.chomp('?')
78
- @type + s[0].capitalize + s[1..-1]
79
- end
80
- end
81
- end # Code
82
-
83
-
84
- =begin rdoc
85
- Indicates that the type class including this module provides the assignment operation.
86
- The user-defined function is assigned to the key +:assign+ and
87
- is expected to have the signature +type+ _assignment-function_(+type+).
88
- The C function provided might return its argument or a new copy. It is also responsible for such things like ownership management etc.
89
- When no user-defined function is specified, this module generates simple value assignment with = operator.
90
- =end
91
- module Assignable
92
- Methods = [:assign] # :nodoc:
93
- # Returns +true+ when used-defined assignment function is specified and +false+ otherwise.
94
- def assign?
95
- !descriptor[:assign].nil?
96
- end
97
- # Returns string representing the C assignment expression for +obj+.
98
- # +obj+ is a string-like object containing the C expression to be injected.
99
- def assign(obj)
100
- assign? ? "#{descriptor[:assign]}(#{obj})" : "(#{obj})"
101
- end
102
- # :nodoc:
103
- def write_intf_assign(stream)
104
- stream << "#{type} #{descriptor[:assign]}(#{type});" if assign?
105
- end
106
- end # Assignable
107
-
108
-
109
- =begin rdoc
110
- Indicates that the type class including this module provides the equality testing operation.
111
- The user-defined function is assigned to the key +:equal+
112
- and is expected to have the signature int _equality-function_(+type+, +type+).
113
- The C function provided must return non-zero value when the values are considered equal and zero value otherwise.
114
- When no user-defined function is specified, this module generates simple value identity testing with == operator.
115
- =end
116
- module EqualityTestable
117
- Methods = [:equal] # :nodoc:
118
- # Returns +true+ when used-defined equality testing function is specified and +false+ otherwise.
119
- def equal?
120
- !descriptor[:equal].nil?
121
- end
122
- # Returns string representing the C expression comparison of +lt+ and +rt+.
123
- # +lt+ and +rt+ are the string-like objects containing the C expression to be injected.
124
- def equal(lt, rt)
125
- equal? ? "#{descriptor[:equal]}(#{lt},#{rt})" : "(#{lt}==#{rt})"
126
- end
127
- # :nodoc:
128
- def write_intf_equal(stream)
129
- stream << "int #{descriptor[:equal]}(#{type},#{type});" if equal?
130
- end
131
- end # EqualityTestable
132
-
133
-
134
- =begin rdoc
135
- Indicates that the type class including this module provides the comparison operation.
136
- The user-defined function is assigned to the key +:compare+
137
- and is expected to have the signature int _compare-function_(+type+, +type+).
138
- The C function provided must return value greater than zero when the first argument is considered greater than the second,
139
- value less than zero when the first argument is considered smaller than the second and zero value when the two arguments are
140
- considered equal.
141
- When no user-defined function is specified, this module generates simple value comparison with < and > operators.
142
- =end
143
- module Comparable
144
- Methods = [:compare] # :nodoc:
145
- # Returns +true+ when wither used-defined or default equality testing function is specified and +false+ otherwise.
146
- def compare?
147
- descriptor.include?(:compare)
148
- end
149
- # Returns string representing the C expression comparison of +lt+ and +rt+.
150
- # +lt+ and +rt+ are the string-like objects containing the C expression to be injected.
151
- def compare(lt, rt)
152
- compare = descriptor[:compare]
153
- compare.nil? ? "(#{lt} > #{rt} ? +1 : (#{lt} < #{rt} ? -1 : 0))" : "#{compare}(#{lt},#{rt})"
154
- end
155
- # :nodoc:
156
- def write_intf_compare(stream)
157
- compare = descriptor[:compare]
158
- stream << "int #{compare}(#{type},#{type});" unless compare.nil?
159
- end
160
- end # Comparable
161
-
162
-
163
- =begin rdoc
164
- Indicates that the type class including this module provides the hash code calculation.
165
- The user-defined function is assigned to the key +:hash+
166
- and is expected to have the signature +size_t+ _hash-function_(+type+).
167
- The C function provided is expected to return a hash code of its argument.
168
- When no user-defined function is specified, this module generates simple casting to the +size_t+ type.
169
- =end
170
- module Hashable
171
- Methods = [:hash] # :nodoc:
172
- # Returns +true+ when used-defined hashing function is specified and +false+ otherwise.
173
- def hash?
174
- !descriptor[:hash].nil?
175
- end
176
- # Returns string representing the C hashing expression for +obj+.
177
- # +obj+ is a string-like object containing the C expression to be injected.
178
- def hash(obj)
179
- hash? ? "#{descriptor[:hash]}(#{obj})" : "((size_t)(#{obj}))" # TODO really size_t?
180
- end
181
- # :nodoc:
182
- def write_intf_hash(stream)
183
- stream << "size_t #{descriptor[:hash]}(#{type});" if hash?
184
- end
185
- end # Hashable
186
-
187
-
188
- =begin rdoc
189
- Indicates that the type class including this module provides the type construction with default value.
190
- The user-defined function is assigned to the key +:ctor+
191
- and is expected to have the signature +type+ _ctor-function_(+void+).
192
- The C function provided is expected to return a new object initialized with default values.
193
- When no user-defined function is specified, this module generates no code at all leaving the storage uninitialized.
194
- =end
195
- module Constructible
196
- Methods = [:ctor] # :nodoc:
197
- # Returns +true+ when used-defined construction function is specified and +false+ otherwise.
198
- def ctor?
199
- !descriptor[:ctor].nil?
200
- end
201
- # Returns string representing the C construction expression.
202
- def ctor
203
- ctor? ? "#{descriptor[:ctor]}()" : nil
204
- end
205
- # :nodoc:
206
- def write_intf_ctor(stream)
207
- stream << "#{type} #{descriptor[:ctor]}(void);" if ctor?
208
- end
209
- end # Constructible
210
-
211
-
212
- =begin rdoc
213
- Indicates that the type class including this module provides the type destruction.
214
- The user-defined function is assigned to the key +:dtor+
215
- and is expected to have the signature +void+ _dtor-function_(+type+).
216
- The C function provided is expected to fully destroy the object (decrease reference count, reclaim the storage, whatever).
217
- When no user-defined function is specified, this module generates no code at all.
218
- The object destruction is performed prior the container destruction, on object removal/replacement.
219
- =end
220
- module Destructible
221
- Methods = [:dtor] # :nodoc:
222
- # Returns +true+ when used-defined construction function is specified and +false+ otherwise.
223
- def dtor?
224
- !descriptor[:dtor].nil?
225
- end
226
- # Returns string representing the C construction expression.
227
- def dtor(obj)
228
- dtor? ? "#{descriptor[:dtor]}(#{obj})" : nil
229
- end
230
- # :nodoc:
231
- def write_intf_dtor(stream)
232
- stream << "void #{descriptor[:dtor]}(#{type});" if dtor?
233
- end
234
- end # Destructible
235
-
236
-
237
- =begin rdoc
238
- Base class for user-defined data types intended to be put into the generated data containers.
239
- A descendant of this class is assumed to include one or more the following capability modules to indicate that
240
- the type supports specific operation: rdoc-ref:Assignable rdoc-ref:Equal rdoc-ref:Hashable rdoc-ref:Constructible rdoc-ref:Destructible
241
- =end
242
- class Type
243
- ##
244
- # String representing C type. Must be a valid C type declaration.
245
- attr_reader :type
246
- ##
247
- # Constructs the user-defined data type.
248
- # +descriptor+ is a +Hash+-like object describing the type to be created.
249
- # The only mandatory key is +:type+ which is set to the C type declaration.
250
- # The rest of specified keys is type-specific and is determined by included capability modules.
251
- #
252
- # === type description examples
253
- #
254
- # [1] A simple integer data type with value semantics and no user-defined functions attached: {:type=>'int'}.
255
- #
256
- # [2] A generic untyped pointer data type with value semantics: {:type=>'void*'}.
257
- # A value of this type is not owned by container so no ownership management is performed.
258
- #
259
- # [3] A pointer to a structure with reference semantics and used-defined operations:
260
- # {:type=>'struct Point*', :assign=>'PointPtrAssign', :dtor=>'PointPtrDtor'}.
261
- # A value of this type will be owned by container.
262
- def initialize(descriptor)
263
- @descriptor = descriptor
264
- @type = descriptor[:type]
265
- end
266
- # :nodoc:
267
- def write_intf(stream)
268
- methods = []
269
- self.class.included_modules.each do |m|
270
- begin
271
- methods.concat(m::Methods)
272
- rescue NameError
273
- end
274
- end
275
- methods.each do |m|
276
- send("write_intf_#{m}", stream)
277
- end
278
- end
279
- # May be nil.
280
- def code
281
- descriptor.is_a?(CodeBuilder::Code) ? descriptor : (descriptor[:forward] ? ForwardCode.new(descriptor[:forward]) : nil)
282
- end
283
- protected
284
- ##
285
- # Used by included modules to retrieve the type description supplied to constructor.
286
- attr_reader :descriptor
287
- end # Type
288
-
289
-
290
- # :nodoc:
291
- class ForwardCode < CodeBuilder::Code
292
- attr_reader :forward
293
- def priority
294
- CodeBuilder::Priority::MAX
295
- end
296
- def initialize(forward)
297
- @forward = forward
298
- end
299
- def write_intf(stream)
300
- stream << forward
301
- end
302
- def hash
303
- forward.hash
304
- end
305
- def ==(other)
306
- equal?(other) || self.class == other.class && self.forward == other.forward
307
- end
308
- alias :eql? :==
309
- end # ForwardCode
310
-
311
-
312
- module Writers
313
- Visibilities = Set.new [:public, :private, :static]
314
- def initialize(type, visibility = :public)
315
- super(type)
316
- raise unless Visibilities.include?(visibility)
317
- @visibility = visibility
318
- end
319
- # :nodoc:
320
- def write_intf(stream)
321
- case @visibility
322
- when :public
323
- write_exported_types(stream)
324
- write_exported_declarations(stream, extern, inline)
325
- end
326
- end
327
- # :nodoc:
328
- def write_decls(stream)
329
- case @visibility
330
- when :private
331
- write_exported_types(stream)
332
- write_exported_declarations(stream, extern, inline)
333
- when :static
334
- write_exported_types(stream)
335
- write_exported_declarations(stream, static, inline)
336
- end
337
- end
338
- # :nodoc:
339
- def write_defs(stream)
340
- case @visibility
341
- when :public, :private
342
- write_implementations(stream, nil)
343
- when :static
344
- write_implementations(stream, static)
345
- end
346
- end
347
- # def write_exported_types(stream)
348
- # def write_exported_declarations(stream, declare, define)
349
- # def write_implementations(stream, define)
350
- end # Writers
351
-
352
-
353
- ##
354
- # Internal base class for data structures which need one types specification, such as vectors, sets etc.
355
- class Structure < Code
356
- include Writers
357
- attr_reader :element
358
- # :nodoc:
359
- def initialize(type, element_descriptor, visibility = :public)
360
- super(type, visibility)
361
- @element = new_element_type(element_descriptor)
362
- @self_hash = {:type=>"#{type}*", :assign=>assign, :ctor=>new, :dtor=>destroy}
363
- end
364
- # :nodoc:
365
- def [](symbol)
366
- @self_hash[symbol]
367
- end
368
- # :nodoc:
369
- def entities; [PrologueCode, @element.code].compact end
370
- # :nodoc:
371
- def write_intf(stream)
372
- element.write_intf(stream)
373
- super
374
- end
375
- # def new_element_type()
376
- end # Struct
377
-
378
-
379
- =begin rdoc
380
- Data structure representing simple light-weight vector with capabilities similar to C array, with optional bounds checking.
381
- =end
382
- class Vector < Structure
383
- def initialize(*args)
384
- super
385
- @self_hash.delete(:ctor) # unlike other data structures, Vector has no parameterless constructor
386
- end
387
- # :nodoc:
388
- def write_exported_types(stream)
389
- stream << %$
390
- typedef struct #{type} #{type};
391
- typedef struct #{it} #{it};
392
- struct #{type} {
393
- #{element.type}* values;
394
- size_t element_count;
395
- size_t ref_count;
396
- };
397
- struct #{it} {
398
- #{type}* vector;
399
- size_t index;
400
- };
401
- $
402
- end
403
- def write_exported_declarations(stream, declare, define)
404
- stream << %$
405
- #{declare} void #{ctor}(#{type}*, size_t);
406
- #{declare} void #{dtor}(#{type}*);
407
- #{declare} #{type}* #{new}(size_t);
408
- #{declare} void #{destroy}(#{type}*);
409
- #{declare} #{type}* #{assign}(#{type}*);
410
- #{declare} void #{resize}(#{type}*, size_t);
411
- #{declare} int #{within}(#{type}*, size_t);
412
- #{declare} void #{itCtor}(#{it}*, #{type}*);
413
- #{declare} int #{itHasNext}(#{it}*);
414
- #{declare} #{element.type} #{itNext}(#{it}*);
415
- #{define} #{element.type}* #{ref}(#{type}* self, size_t index) {
416
- #{assert}(self);
417
- #{assert}(#{within}(self, index));
418
- return &self->values[index];
419
- }
420
- #{define} #{element.type} #{get}(#{type}* self, size_t index) {
421
- #{assert}(self);
422
- #{assert}(#{within}(self, index));
423
- return *#{ref}(self, index);
424
- }
425
- #{define} void #{set}(#{type}* self, size_t index, #{element.type} value) {
426
- #{element.type}* ref;
427
- #{assert}(self);
428
- #{assert}(#{within}(self, index));
429
- ref = #{ref}(self, index);
430
- #{element.dtor("*ref")};
431
- *ref = #{element.assign(:value)};
432
- }
433
- #{define} size_t #{size}(#{type}* self) {
434
- #{assert}(self);
435
- return self->element_count;
436
- }
437
- $
438
- stream << %$#{declare} void #{sort}(#{type}*);$ if element.compare?
439
- end
440
- # :nodoc:
441
- def write_implementations(stream, define)
442
- stream << %$
443
- #{define} void #{ctor}(#{type}* self, size_t element_count) {
444
- #{assert}(self);
445
- #{assert}(element_count > 0);
446
- self->element_count = element_count;
447
- self->values = (#{element.type}*)#{calloc}(element_count, sizeof(#{element.type})); #{assert}(self->values);
448
- #{construct_stmt("self->values", 0, "self->element_count-1")};
449
- }
450
- #{define} void #{dtor}(#{type}* self) {
451
- #{assert}(self);
452
- #{destruct_stmt("self->values", 0, "self->element_count-1")};
453
- #{free}(self->values);
454
- }
455
- #{define} #{type}* #{new}(size_t element_count) {
456
- #{type}* self = (#{type}*)#{malloc}(sizeof(#{type})); #{assert}(self);
457
- #{ctor}(self, element_count);
458
- self->ref_count = 0;
459
- return self;
460
- }
461
- #{define} void #{destroy}(#{type}* self) {
462
- #{assert}(self);
463
- if(!--self->ref_count) {
464
- #{dtor}(self);
465
- #{free}(self);
466
- }
467
- }
468
- #{define} #{type}* #{assign}(#{type}* self) {
469
- ++self->ref_count;
470
- return self;
471
- }
472
- #{define} void #{resize}(#{type}* self, size_t element_count) {
473
- #{assert}(self);
474
- if(self->element_count != element_count) {
475
- size_t count;
476
- #{element.type}* values = (#{element.type}*)#{calloc}(element_count, sizeof(#{element.type})); #{assert}(values);
477
- if(self->element_count > element_count) {
478
- #{destruct_stmt("self->values", "element_count", "self->element_count-1")};
479
- count = element_count;
480
- } else {
481
- #{construct_stmt("values", "self->element_count", "element_count-1")};
482
- count = self->element_count;
483
- }
484
- {
485
- size_t index;
486
- for(index = 0; index < count; ++index) {
487
- values[index] = self->values[index];
488
- }
489
- }
490
- #{free}(self->values);
491
- self->element_count = element_count;
492
- self->values = values;
493
- }
494
- }
495
- #{define} int #{within}(#{type}* self, size_t index) {
496
- #{assert}(self);
497
- return index < self->element_count;
498
- }
499
- #{define} void #{itCtor}(#{it}* self, #{type}* vector) {
500
- #{assert}(self);
501
- #{assert}(vector);
502
- self->vector = vector;
503
- self->index = 0;
504
- }
505
- #{define} int #{itHasNext}(#{it}* self) {
506
- #{assert}(self);
507
- return self->index < #{size}(self->vector);
508
- }
509
- #{define} #{element.type} #{itNext}(#{it}* self) {
510
- #{assert}(self);
511
- return #{get}(self->vector, self->index++);
512
- }
513
- $
514
- stream << %$
515
- static int #{comparator}(const void* lp, const void* rp) {
516
- return #{element.compare("*(#{element.type}*)lp", "*(#{element.type}*)rp")};
517
- }
518
- #{define} void #{sort}(#{type}* self) {
519
- #{assert}(self);
520
- qsort(self->values, self->element_count, sizeof(#{element.type}), #{comparator});
521
- }
522
- $ if element.compare?
523
- end
524
- protected
525
- # :nodoc:
526
- class ElementType < DataStructBuilder::Type
527
- include Assignable, Constructible, Destructible, Comparable
528
- end # ElementType
529
- # :nodoc:
530
- def new_element_type(type)
531
- ElementType.new(type)
532
- end
533
- private
534
- # :nodoc:
535
- def construct_stmt(values, from, to)
536
- if element.ctor?
537
- %${
538
- size_t index;
539
- for(index = #{from}; index <= #{to}; ++index) #{values}[index] = #{element.assign(element.ctor())};
540
- }$
541
- end
542
- end
543
- # :nodoc:
544
- def destruct_stmt(values, from, to)
545
- if element.dtor?
546
- %${
547
- size_t index;
548
- for(index = #{from}; index <= #{to}; ++index) #{element.dtor(values+"[index]")};
549
- }$
550
- end
551
- end
552
- end # Vector
553
-
554
-
555
- =begin rdoc
556
- Data structure representing singly-linked list.
557
- =end
558
- class List < Structure
559
- # :nodoc:
560
- def write_exported_types(stream)
561
- stream << %$
562
- typedef struct #{node} #{node};
563
- typedef struct #{type} #{type};
564
- typedef struct #{it} #{it};
565
- struct #{type} {
566
- #{node}* head_node;
567
- size_t node_count;
568
- size_t ref_count;
569
- };
570
- struct #{it} {
571
- #{node}* next_node;
572
- };
573
- struct #{node} {
574
- #{element.type} element;
575
- #{node}* next_node;
576
- };
577
- $
578
- end
579
- # :nodoc:
580
- def write_exported_declarations(stream, declare, define)
581
- stream << %$
582
- #{declare} void #{ctor}(#{type}*);
583
- #{declare} void #{dtor}(#{type}*);
584
- #{declare} void #{purge}(#{type}*);
585
- #{declare} #{type}* #{new}(void);
586
- #{declare} void #{destroy}(#{type}*);
587
- #{declare} #{type}* #{assign}(#{type}*);
588
- #{declare} #{element.type} #{get}(#{type}*);
589
- #{declare} void #{add}(#{type}*, #{element.type});
590
- #{declare} void #{chop}(#{type}*);
591
- #{declare} int #{contains}(#{type}*, #{element.type});
592
- #{declare} #{element.type} #{find}(#{type}*, #{element.type});
593
- #{declare} int #{replace}(#{type}*, #{element.type}, #{element.type});
594
- #{declare} int #{replaceAll}(#{type}*, #{element.type}, #{element.type});
595
- #{declare} int #{remove}(#{type}*, #{element.type});
596
- #{declare} int #{removeAll}(#{type}*, #{element.type});
597
- #{declare} size_t #{size}(#{type}*);
598
- #{declare} int #{empty}(#{type}*);
599
- #{declare} void #{itCtor}(#{it}*, #{type}*);
600
- #{declare} int #{itHasNext}(#{it}*);
601
- #{declare} #{element.type} #{itNext}(#{it}*);
602
- $
603
- end
604
- # :nodoc:
605
- def write_implementations(stream, define)
606
- stream << %$
607
- #{define} void #{ctor}(#{type}* self) {
608
- #{assert}(self);
609
- self->head_node = NULL;
610
- self->node_count = 0;
611
- }
612
- #{define} void #{dtor}(#{type}* self) {
613
- #{node}* node;
614
- #{assert}(self);
615
- #{destruct_stmt};
616
- node = self->head_node;
617
- while(node) {
618
- #{node}* this_node = node;
619
- node = node->next_node;
620
- #{free}(this_node);
621
- }
622
- }
623
- #{define} #{type}* #{new}(void) {
624
- #{type}* self = (#{type}*)#{malloc}(sizeof(#{type})); #{assert}(self);
625
- #{ctor}(self);
626
- self->ref_count = 0;
627
- return self;
628
- }
629
- #{define} void #{destroy}(#{type}* self) {
630
- #{assert}(self);
631
- if(!--self->ref_count) {
632
- #{dtor}(self);
633
- #{free}(self);
634
- }
635
- }
636
- #{define} #{type}* #{assign}(#{type}* self) {
637
- ++self->ref_count;
638
- return self;
639
- }
640
- #{define} void #{purge}(#{type}* self) {
641
- #{dtor}(self);
642
- #{ctor}(self);
643
- }
644
- #{define} #{element.type} #{get}(#{type}* self) {
645
- #{assert}(self);
646
- #{assert}(!#{empty}(self));
647
- return self->head_node->element;
648
- }
649
- #{define} void #{chop}(#{type}* self) {
650
- #{node}* node;
651
- #{assert}(self);
652
- #{assert}(!#{empty}(self));
653
- node = self->head_node;
654
- #{element.dtor("node->element")};
655
- self->head_node = self->head_node->next_node;
656
- --self->node_count;
657
- #{free}(node);
658
- }
659
- #{define} void #{add}(#{type}* self, #{element.type} element) {
660
- #{node}* node;
661
- #{assert}(self);
662
- node = (#{node}*)#{malloc}(sizeof(#{node})); #{assert}(node);
663
- node->element = #{element.assign("element")};
664
- node->next_node = self->head_node;
665
- self->head_node = node;
666
- ++self->node_count;
667
- }
668
- #{define} int #{contains}(#{type}* self, #{element.type} what) {
669
- #{node}* node;
670
- #{assert}(self);
671
- what = #{element.assign("what")};
672
- node = self->head_node;
673
- while(node) {
674
- if(#{element.equal("node->element", "what")}) {
675
- #{element.dtor("what")};
676
- return 1;
677
- }
678
- node = node->next_node;
679
- }
680
- #{element.dtor("what")};
681
- return 0;
682
- }
683
- #{define} #{element.type} #{find}(#{type}* self, #{element.type} what) {
684
- #{node}* node;
685
- #{assert}(self);
686
- what = #{element.assign("what")};
687
- #{assert}(#{contains}(self, what));
688
- node = self->head_node;
689
- while(node) {
690
- if(#{element.equal("node->element", "what")}) {
691
- #{element.dtor("what")};
692
- return node->element;
693
- }
694
- node = node->next_node;
695
- }
696
- #{abort}();
697
- }
698
- #{define} int #{replace}(#{type}* self, #{element.type} what, #{element.type} with) {
699
- #{node}* node;
700
- #{assert}(self);
701
- what = #{element.assign("what")};
702
- with = #{element.assign("with")};
703
- node = self->head_node;
704
- while(node) {
705
- if(#{element.equal("node->element", "what")}) {
706
- #{element.dtor("node->element")};
707
- node->element = #{element.assign("with")};
708
- #{element.dtor("what")};
709
- #{element.dtor("with")};
710
- return 1;
711
- }
712
- node = node->next_node;
713
- }
714
- #{element.dtor("what")};
715
- #{element.dtor("with")};
716
- return 0;
717
- }
718
- #{define} int #{replaceAll}(#{type}* self, #{element.type} what, #{element.type} with) {
719
- #{node}* node;
720
- int count = 0;
721
- #{assert}(self);
722
- what = #{element.assign("what")};
723
- with = #{element.assign("with")};
724
- node = self->head_node;
725
- while(node) {
726
- if(#{element.equal("node->element", "what")}) {
727
- #{element.dtor("node->element")};
728
- node->element = #{element.assign("with")};
729
- ++count;
730
- }
731
- node = node->next_node;
732
- }
733
- #{element.dtor("what")};
734
- #{element.dtor("with")};
735
- return count;
736
- }
737
- #{define} int #{remove}(#{type}* self, #{element.type} what) {
738
- #{node}* node;
739
- #{node}* prev_node;
740
- int found = 0;
741
- #{assert}(self);
742
- what = #{element.assign("what")};
743
- node = self->head_node;
744
- prev_node = NULL;
745
- while(node) {
746
- if(#{element.equal("node->element", "what")}) {
747
- #{element.dtor("node->element")};
748
- if(prev_node) {
749
- prev_node->next_node = node->next_node ? node->next_node : NULL;
750
- } else {
751
- self->head_node = node->next_node ? node->next_node : NULL;
752
- }
753
- --self->node_count;
754
- #{free}(node);
755
- found = 1;
756
- break;
757
- }
758
- prev_node = node;
759
- node = node->next_node;
760
- }
761
- #{element.dtor("what")};
762
- return found;
763
- }
764
- #{define} int #{removeAll}(#{type}* self, #{element.type} what) {
765
- #{node}* node;
766
- #{node}* prev_node;
767
- int count = 0;
768
- #{assert}(self);
769
- what = #{element.assign("what")};
770
- node = self->head_node;
771
- prev_node = NULL;
772
- while(node) {
773
- if(#{element.equal("node->element", "what")}) {
774
- #{element.dtor("node->element")};
775
- if(prev_node) {
776
- prev_node->next_node = node->next_node ? node->next_node : NULL;
777
- } else {
778
- self->head_node = node->next_node ? node->next_node : NULL;
779
- }
780
- --self->node_count;
781
- #{free}(node);
782
- ++count;
783
- }
784
- prev_node = node;
785
- node = node->next_node;
786
- }
787
- #{element.dtor("what")};
788
- return count;
789
- }
790
- #{define} size_t #{size}(#{type}* self) {
791
- #{assert}(self);
792
- return self->node_count;
793
- }
794
- #{define} int #{empty}(#{type}* self) {
795
- #{assert}(self);
796
- return !self->node_count;
797
- }
798
- #{define} void #{itCtor}(#{it}* self, #{type}* list) {
799
- #{assert}(self);
800
- #{assert}(list);
801
- self->next_node = list->head_node;
802
- }
803
- #{define} int #{itHasNext}(#{it}* self) {
804
- #{assert}(self);
805
- return self->next_node != NULL;
806
- }
807
- #{define} #{element.type} #{itNext}(#{it}* self) {
808
- #{node}* node;
809
- #{assert}(self);
810
- node = self->next_node;
811
- self->next_node = self->next_node->next_node;
812
- return node->element;
813
- }
814
- $
815
- end
816
- protected
817
- # :nodoc:
818
- class ElementType < DataStructBuilder::Type
819
- include Assignable, Destructible, EqualityTestable
820
- end # ElementType
821
- # :nodoc:
822
- def new_element_type(hash)
823
- ElementType.new(hash)
824
- end
825
- private
826
- # :nodoc:
827
- def destruct_stmt
828
- if element.dtor?
829
- %${
830
- #{it} it;
831
- #{itCtor}(&it, self);
832
- while(#{itHasNext}(&it)) {
833
- #{element.type} e = #{itNext}(&it);
834
- #{element.dtor(:e)};
835
- }
836
- }$
837
- end
838
- end
839
- end # List
840
-
841
-
842
- =begin rdoc
843
- Data structure representing doubly-linked list.
844
- =end
845
- class Queue < Structure
846
- # :nodoc:
847
- def write_exported_types(stream)
848
- stream << %$
849
- typedef struct #{node} #{node};
850
- typedef struct #{type} #{type};
851
- typedef struct #{it} #{it};
852
- struct #{type} {
853
- #{node}* head_node;
854
- #{node}* tail_node;
855
- size_t node_count;
856
- size_t ref_count;
857
- };
858
- struct #{it} {
859
- #{node}* next_node;
860
- int forward;
861
- };
862
- struct #{node} {
863
- #{element.type} element;
864
- #{node}* prev_node;
865
- #{node}* next_node;
866
- };
867
- $
868
- end
869
- # :nodoc:
870
- def write_exported_declarations(stream, declare, define)
871
- stream << %$
872
- #{declare} void #{ctor}(#{type}*);
873
- #{declare} void #{dtor}(#{type}*);
874
- #{declare} void #{purge}(#{type}*);
875
- #{declare} #{type}* #{new}(void);
876
- #{declare} void #{destroy}(#{type}*);
877
- #{declare} #{type}* #{assign}(#{type}*);
878
- #{declare} #{element.type} #{head}(#{type}*);
879
- #{declare} #{element.type} #{tail}(#{type}*);
880
- #{declare} void #{append}(#{type}*, #{element.type});
881
- #{declare} void #{prepend}(#{type}*, #{element.type});
882
- #{declare} void #{chopHead}(#{type}*);
883
- #{declare} void #{chopTail}(#{type}*);
884
- #{declare} int #{contains}(#{type}*, #{element.type});
885
- #{declare} #{element.type} #{find}(#{type}*, #{element.type});
886
- #{declare} int #{replace}(#{type}*, #{element.type}, #{element.type});
887
- #{declare} int #{replaceAll}(#{type}*, #{element.type}, #{element.type});
888
- #{declare} int #{remove}(#{type}*, #{element.type});
889
- #{declare} int #{removeAll}(#{type}*, #{element.type});
890
- #{declare} size_t #{size}(#{type}*);
891
- #{declare} int #{empty}(#{type}*);
892
- #{declare} void #{itCtor}(#{it}*, #{type}*, int);
893
- #{declare} int #{itHasNext}(#{it}*);
894
- #{declare} #{element.type} #{itNext}(#{it}*);
895
- $
896
- end
897
- # :nodoc:
898
- def write_implementations(stream, define)
899
- stream << %$
900
- #{define} void #{ctor}(#{type}* self) {
901
- #{assert}(self);
902
- self->head_node = self->tail_node = NULL;
903
- self->node_count = 0;
904
- }
905
- #{define} void #{dtor}(#{type}* self) {
906
- #{node}* node;
907
- #{assert}(self);
908
- #{destruct_stmt};
909
- node = self->head_node;
910
- while(node) {
911
- #{node}* this_node = node;
912
- node = node->next_node;
913
- #{free}(this_node);
914
- }
915
- }
916
- #{define} #{type}* #{new}(void) {
917
- #{type}* self = (#{type}*)#{malloc}(sizeof(#{type})); #{assert}(self);
918
- #{ctor}(self);
919
- self->ref_count = 0;
920
- return self;
921
- }
922
- #{define} void #{destroy}(#{type}* self) {
923
- #{assert}(self);
924
- if(!--self->ref_count) {
925
- #{dtor}(self);
926
- #{free}(self);
927
- }
928
- }
929
- #{define} #{type}* #{assign}(#{type}* self) {
930
- ++self->ref_count;
931
- return self;
932
- }
933
- #{define} void #{purge}(#{type}* self) {
934
- #{dtor}(self);
935
- #{ctor}(self);
936
- }
937
- #{define} #{element.type} #{head}(#{type}* self) {
938
- #{assert}(self);
939
- #{assert}(!#{empty}(self));
940
- return self->head_node->element;
941
- }
942
- #{define} #{element.type} #{tail}(#{type}* self) {
943
- #{assert}(self);
944
- #{assert}(!#{empty}(self));
945
- return self->tail_node->element;
946
- }
947
- #{define} void #{chopHead}(#{type}* self) {
948
- #{node}* node;
949
- #{assert}(self);
950
- #{assert}(!#{empty}(self));
951
- node = self->head_node;
952
- #{element.dtor("node->element")};
953
- self->head_node = self->head_node->next_node;
954
- self->head_node->prev_node = NULL;
955
- --self->node_count;
956
- #{free}(node);
957
- }
958
- #{define} void #{chopTail}(#{type}* self) {
959
- #{node}* node;
960
- #{assert}(self);
961
- #{assert}(!#{empty}(self));
962
- node = self->tail_node;
963
- #{element.dtor("node->element")};
964
- self->tail_node = self->tail_node->prev_node;
965
- self->tail_node->next_node = NULL;
966
- --self->node_count;
967
- #{free}(node);
968
- }
969
- #{define} void #{append}(#{type}* self, #{element.type} element) {
970
- #{node}* node;
971
- #{assert}(self);
972
- node = (#{node}*)#{malloc}(sizeof(#{node})); #{assert}(node);
973
- node->element = #{element.assign("element")};
974
- if(#{empty}(self)) {
975
- node->prev_node = node->next_node = NULL;
976
- self->tail_node = self->head_node = node;
977
- } else {
978
- node->next_node = NULL;
979
- node->prev_node = self->tail_node;
980
- self->tail_node->next_node = node;
981
- self->tail_node = node;
982
- }
983
- ++self->node_count;
984
- }
985
- #{define} void #{prepend}(#{type}* self, #{element.type} element) {
986
- #{node}* node;
987
- #{assert}(self);
988
- node = (#{node}*)#{malloc}(sizeof(#{node})); #{assert}(node);
989
- node->element = #{element.assign("element")};
990
- if(#{empty}(self)) {
991
- node->prev_node = node->next_node = NULL;
992
- self->tail_node = self->head_node = node;
993
- } else {
994
- node->prev_node = NULL;
995
- node->next_node = self->head_node;
996
- self->head_node->prev_node = node;
997
- self->head_node = node;
998
- }
999
- ++self->node_count;
1000
- }
1001
- #{define} int #{contains}(#{type}* self, #{element.type} what) {
1002
- #{node}* node;
1003
- #{assert}(self);
1004
- what = #{element.assign("what")};
1005
- node = self->head_node;
1006
- while(node) {
1007
- if(#{element.equal("node->element", "what")}) {
1008
- #{element.dtor("what")};
1009
- return 1;
1010
- }
1011
- node = node->next_node;
1012
- }
1013
- #{element.dtor("what")};
1014
- return 0;
1015
- }
1016
- #{define} #{element.type} #{find}(#{type}* self, #{element.type} what) {
1017
- #{node}* node;
1018
- #{assert}(self);
1019
- what = #{element.assign("what")};
1020
- #{assert}(#{contains}(self, what));
1021
- node = self->head_node;
1022
- while(node) {
1023
- if(#{element.equal("node->element", "what")}) {
1024
- #{element.dtor("what")};
1025
- return node->element;
1026
- }
1027
- node = node->next_node;
1028
- }
1029
- #{abort}();
1030
- }
1031
- #{define} int #{replace}(#{type}* self, #{element.type} what, #{element.type} with) {
1032
- #{node}* node;
1033
- #{assert}(self);
1034
- what = #{element.assign("what")};
1035
- with = #{element.assign("with")};
1036
- node = self->head_node;
1037
- while(node) {
1038
- if(#{element.equal("node->element", "what")}) {
1039
- #{element.dtor("node->element")};
1040
- node->element = #{element.assign("with")};
1041
- #{element.dtor("what")};
1042
- #{element.dtor("with")};
1043
- return 1;
1044
- }
1045
- node = node->next_node;
1046
- }
1047
- #{element.dtor("what")};
1048
- #{element.dtor("with")};
1049
- return 0;
1050
- }
1051
- #{define} int #{replaceAll}(#{type}* self, #{element.type} what, #{element.type} with) {
1052
- #{node}* node;
1053
- int count = 0;
1054
- #{assert}(self);
1055
- what = #{element.assign("what")};
1056
- with = #{element.assign("with")};
1057
- node = self->head_node;
1058
- while(node) {
1059
- if(#{element.equal("node->element", "what")}) {
1060
- #{element.dtor("node->element")};
1061
- node->element = #{element.assign("with")};
1062
- ++count;
1063
- }
1064
- node = node->next_node;
1065
- }
1066
- #{element.dtor("what")};
1067
- #{element.dtor("with")};
1068
- return count;
1069
- }
1070
- #{define} int #{remove}(#{type}* self, #{element.type} what) {
1071
- #{node}* node;
1072
- int found = 0;
1073
- #{assert}(self);
1074
- what = #{element.assign("what")};
1075
- node = self->head_node;
1076
- while(node) {
1077
- if(#{element.equal("node->element", "what")}) {
1078
- #{node} *prev = node->prev_node, *next = node->next_node;
1079
- #{element.dtor("node->element")};
1080
- if(prev && next) {
1081
- prev->next_node = next;
1082
- next->prev_node = prev;
1083
- } else if(prev) {
1084
- prev->next_node = NULL;
1085
- self->tail_node = prev;
1086
- } else {
1087
- next->prev_node = NULL;
1088
- self->head_node = next;
1089
- }
1090
- --self->node_count;
1091
- #{free}(node);
1092
- found = 1;
1093
- break;
1094
- }
1095
- node = node->next_node;
1096
- }
1097
- #{element.dtor("what")};
1098
- return found;
1099
- }
1100
- #{define} int #{removeAll}(#{type}* self, #{element.type} what) {
1101
- #{node}* node;
1102
- int count = 0;
1103
- #{assert}(self);
1104
- what = #{element.assign("what")};
1105
- node = self->head_node;
1106
- while(node) {
1107
- if(#{element.equal("node->element", "what")}) {
1108
- #{node} *prev = node->prev_node, *next = node->next_node;
1109
- #{element.dtor("node->element")};
1110
- if(prev && next) {
1111
- prev->next_node = next;
1112
- next->prev_node = prev;
1113
- } else if(prev) {
1114
- prev->next_node = NULL;
1115
- self->tail_node = prev;
1116
- } else {
1117
- next->prev_node = NULL;
1118
- self->head_node = next;
1119
- }
1120
- --self->node_count;
1121
- #{free}(node);
1122
- ++count;
1123
- }
1124
- node = node->next_node;
1125
- }
1126
- #{element.dtor("what")};
1127
- return count;
1128
- }
1129
- #{define} size_t #{size}(#{type}* self) {
1130
- #{assert}(self);
1131
- return self->node_count;
1132
- }
1133
- #{define} int #{empty}(#{type}* self) {
1134
- #{assert}(self);
1135
- return !self->node_count;
1136
- }
1137
- #{define} void #{itCtor}(#{it}* self, #{type}* list, int forward) {
1138
- #{assert}(self);
1139
- #{assert}(list);
1140
- self->forward = forward;
1141
- self->next_node = forward ? list->head_node : list->tail_node;
1142
- }
1143
- #{define} int #{itHasNext}(#{it}* self) {
1144
- #{assert}(self);
1145
- return self->next_node != NULL;
1146
- }
1147
- #{define} #{element.type} #{itNext}(#{it}* self) {
1148
- #{node}* node;
1149
- #{assert}(self);
1150
- node = self->next_node;
1151
- self->next_node = self->forward ? self->next_node->next_node : self->next_node->prev_node;
1152
- return node->element;
1153
- }
1154
- $
1155
- end
1156
- protected
1157
- # :nodoc:
1158
- class ElementType < DataStructBuilder::Type
1159
- include Assignable, Destructible, EqualityTestable
1160
- end # ElementType
1161
- # :nodoc:
1162
- def new_element_type(hash)
1163
- ElementType.new(hash)
1164
- end
1165
- private
1166
- # :nodoc:
1167
- def destruct_stmt
1168
- if element.dtor?
1169
- %${
1170
- #{it} it;
1171
- #{itCtor}(&it, self);
1172
- while(#{itHasNext}(&it)) {
1173
- #{element.type} e = #{itNext}(&it);
1174
- #{element.dtor(:e)};
1175
- }
1176
- }$
1177
- end
1178
- end
1179
- end # Queue
1180
-
1181
-
1182
- =begin rdoc
1183
- Data structure representing hashed set.
1184
- =end
1185
- class HashSet < Structure
1186
- # :nodoc:
1187
- def initialize(*args)
1188
- super
1189
- @list = new_list
1190
- end
1191
- # :nodoc:
1192
- def write_exported_types(stream)
1193
- @list.write_exported_types(stream)
1194
- stream << %$
1195
- typedef struct #{type} #{type};
1196
- typedef struct #{it} #{it};
1197
- struct #{type} {
1198
- #{@list.type}* buckets;
1199
- size_t bucket_count, min_bucket_count;
1200
- size_t size, min_size, max_size;
1201
- unsigned min_fill, max_fill, capacity_multiplier; /* ?*1e-2 */
1202
- size_t ref_count;
1203
- };
1204
- struct #{it} {
1205
- #{type}* set;
1206
- int bucket_index;
1207
- #{@list.it} it;
1208
- };
1209
- $
1210
- end
1211
- def write_exported_declarations(stream, declare, define)
1212
- stream << %$
1213
- #{declare} void #{ctor}(#{type}*);
1214
- #{declare} void #{dtor}(#{type}*);
1215
- #{declare} #{type}* #{new}(void);
1216
- #{declare} void #{destroy}(#{type}*);
1217
- #{declare} #{type}* #{assign}(#{type}*);
1218
- #{declare} void #{purge}(#{type}*);
1219
- #{declare} void #{rehash}(#{type}*);
1220
- #{declare} int #{contains}(#{type}*, #{element.type});
1221
- #{declare} #{element.type} #{get}(#{type}*, #{element.type});
1222
- #{declare} size_t #{size}(#{type}*);
1223
- #{declare} int #{empty}(#{type}*);
1224
- #{declare} int #{put}(#{type}*, #{element.type});
1225
- #{declare} void #{replace}(#{type}*, #{element.type});
1226
- #{declare} int #{remove}(#{type}*, #{element.type});
1227
- #{declare} void #{not?}(#{type}*, #{type}*);
1228
- #{declare} void #{and?}(#{type}*, #{type}*);
1229
- #{declare} void #{or?}(#{type}*, #{type}*);
1230
- #{declare} void #{xor?}(#{type}*, #{type}*);
1231
- #{declare} void #{itCtor}(#{it}*, #{type}*);
1232
- #{declare} int #{itHasNext}(#{it}*);
1233
- #{declare} #{element.type} #{itNext}(#{it}*);
1234
- $
1235
- stream << %$#{declare} void #{dumpStats}(#{type}*, FILE*);$ if $debug
1236
- end
1237
- # :nodoc:
1238
- def write_implementations(stream, define)
1239
- @list.write_exported_declarations(stream, static, inline)
1240
- @list.write_implementations(stream, static)
1241
- stream << %$
1242
- #{define} void #{ctor}(#{type}* self) {
1243
- #{assert}(self);
1244
- self->min_bucket_count = 16;
1245
- self->min_fill = 20;
1246
- self->max_fill = 80;
1247
- self->min_size = (size_t)((float)self->min_fill/100*self->min_bucket_count);
1248
- self->max_size = (size_t)((float)self->max_fill/100*self->min_bucket_count);
1249
- self->capacity_multiplier = 200;
1250
- self->buckets = NULL;
1251
- #{rehash}(self);
1252
- }
1253
- #{define} void #{dtor}(#{type}* self) {
1254
- size_t i;
1255
- #{assert}(self);
1256
- for(i = 0; i < self->bucket_count; ++i) {
1257
- #{@list.dtor}(&self->buckets[i]);
1258
- }
1259
- #{free}(self->buckets);
1260
- }
1261
- #{define} #{type}* #{new}(void) {
1262
- #{type}* self = (#{type}*)#{malloc}(sizeof(#{type})); #{assert}(self);
1263
- #{ctor}(self);
1264
- self->ref_count = 0;
1265
- return self;
1266
- }
1267
- #{define} void #{destroy}(#{type}* self) {
1268
- #{assert}(self);
1269
- if(!--self->ref_count) {
1270
- #{dtor}(self);
1271
- #{free}(self);
1272
- }
1273
- }
1274
- #{define} #{type}* #{assign}(#{type}* self) {
1275
- ++self->ref_count;
1276
- return self;
1277
- }
1278
- #{define} void #{purge}(#{type}* self) {
1279
- #{assert}(self);
1280
- #{dtor}(self);
1281
- self->buckets = NULL;
1282
- #{rehash}(self);
1283
- }
1284
- #{define} void #{rehash}(#{type}* self) {
1285
- #{@list.type}* buckets;
1286
- size_t i, bucket_count, size, fill;
1287
- #{assert}(self);
1288
- #{assert}(self->min_fill > 0);
1289
- #{assert}(self->max_fill > 0);
1290
- #{assert}(self->min_fill < self->max_fill);
1291
- #{assert}(self->min_bucket_count > 0);
1292
- if(self->buckets) {
1293
- if(self->min_size < self->size && self->size < self->max_size) return;
1294
- fill = (size_t)((float)self->size/self->bucket_count*100);
1295
- if(fill > self->max_fill) {
1296
- bucket_count = (size_t)((float)self->bucket_count/100*self->capacity_multiplier);
1297
- } else
1298
- if(fill < self->min_fill && self->bucket_count > self->min_bucket_count) {
1299
- bucket_count = (size_t)((float)self->bucket_count/self->capacity_multiplier*100);
1300
- if(bucket_count < self->min_bucket_count) bucket_count = self->min_bucket_count;
1301
- } else
1302
- return;
1303
- size = self->size;
1304
- self->min_size = (size_t)((float)self->min_fill/100*size);
1305
- self->max_size = (size_t)((float)self->max_fill/100*size);
1306
- } else {
1307
- bucket_count = self->min_bucket_count;
1308
- size = 0;
1309
- }
1310
- buckets = (#{@list.type}*)#{malloc}(bucket_count*sizeof(#{@list.type})); #{assert}(buckets);
1311
- for(i = 0; i < bucket_count; ++i) {
1312
- #{@list.ctor}(&buckets[i]);
1313
- }
1314
- if(self->buckets) {
1315
- #{it} it;
1316
- #{itCtor}(&it, self);
1317
- while(#{itHasNext}(&it)) {
1318
- #{@list.type}* bucket;
1319
- #{element.type} element = #{itNext}(&it);
1320
- bucket = &buckets[#{element.hash("element")} % bucket_count];
1321
- #{@list.add}(bucket, element);
1322
- }
1323
- #{dtor}(self);
1324
- }
1325
- self->buckets = buckets;
1326
- self->bucket_count = bucket_count;
1327
- self->size = size;
1328
- }
1329
- #{define} int #{contains}(#{type}* self, #{element.type} element) {
1330
- int result;
1331
- #{assert}(self);
1332
- element = #{element.assign("element")};
1333
- result = #{@list.contains}(&self->buckets[#{element.hash("element")} % self->bucket_count], element);
1334
- #{element.dtor("element")};
1335
- return result;
1336
- }
1337
- #{define} #{element.type} #{get}(#{type}* self, #{element.type} element) {
1338
- #{element.type} result;
1339
- #{assert}(self);
1340
- element = #{element.assign("element")};
1341
- #{assert}(#{contains}(self, element));
1342
- result = #{@list.find}(&self->buckets[#{element.hash("element")} % self->bucket_count], element);
1343
- #{element.dtor("element")};
1344
- return result;
1345
- }
1346
- #{define} size_t #{size}(#{type}* self) {
1347
- #{assert}(self);
1348
- return self->size;
1349
- }
1350
- #{define} int #{empty}(#{type}* self) {
1351
- #{assert}(self);
1352
- return !self->size;
1353
- }
1354
- #{define} int #{put}(#{type}* self, #{element.type} element) {
1355
- int contained = 1;
1356
- #{@list.type}* bucket;
1357
- #{assert}(self);
1358
- element = #{element.assign("element")};
1359
- bucket = &self->buckets[#{element.hash("element")} % self->bucket_count];
1360
- if(!#{@list.contains}(bucket, element)) {
1361
- #{@list.add}(bucket, element);
1362
- ++self->size;
1363
- contained = 0;
1364
- #{rehash}(self);
1365
- }
1366
- #{element.dtor("element")};
1367
- return contained;
1368
- }
1369
- #{define} void #{replace}(#{type}* self, #{element.type} element) {
1370
- #{@list.type}* bucket;
1371
- #{assert}(self);
1372
- element = #{element.assign("element")};
1373
- bucket = &self->buckets[#{element.hash("element")} % self->bucket_count];
1374
- if(!#{@list.replace}(bucket, element, element)) {
1375
- #{@list.add}(bucket, element);
1376
- ++self->size;
1377
- #{rehash}(self);
1378
- }
1379
- #{element.dtor("element")};
1380
- }
1381
- #{define} int #{remove}(#{type}* self, #{element.type} what) {
1382
- int removed = 0;
1383
- #{@list.type}* bucket;
1384
- #{assert}(self);
1385
- what = #{element.assign("what")};
1386
- bucket = &self->buckets[#{element.hash("what")} % self->bucket_count];
1387
- if(#{@list.remove}(bucket, what)) {
1388
- --self->size;
1389
- removed = 1;
1390
- #{rehash}(self);
1391
- }
1392
- #{element.dtor("what")};
1393
- return removed;
1394
- }
1395
- #{define} void #{not?}(#{type}* self, #{type}* other) {
1396
- #{it} it;
1397
- #{assert}(self);
1398
- #{assert}(other);
1399
- #{itCtor}(&it, other);
1400
- while(#{itHasNext}(&it)) {
1401
- #{remove}(self, #{itNext}(&it));
1402
- }
1403
- #{rehash}(self);
1404
- }
1405
- #{define} void #{or?}(#{type}* self, #{type}* other) {
1406
- #{it} it;
1407
- #{assert}(self);
1408
- #{assert}(other);
1409
- #{itCtor}(&it, other);
1410
- while(#{itHasNext}(&it)) {
1411
- #{put}(self, #{itNext}(&it));
1412
- }
1413
- #{rehash}(self);
1414
- }
1415
- #{define} void #{and?}(#{type}* self, #{type}* other) {
1416
- #{it} it;
1417
- #{type} set;
1418
- #{assert}(self);
1419
- #{assert}(other);
1420
- #{ctor}(&set);
1421
- #{itCtor}(&it, self);
1422
- while(#{itHasNext}(&it)) {
1423
- #{element.type} element = #{itNext}(&it);
1424
- if(#{contains}(other, element)) #{put}(&set, element);
1425
- }
1426
- #{itCtor}(&it, other);
1427
- while(#{itHasNext}(&it)) {
1428
- #{element.type} element = #{itNext}(&it);
1429
- if(#{contains}(self, element)) #{put}(&set, element);
1430
- }
1431
- #{dtor}(self);
1432
- self->buckets = set.buckets;
1433
- self->size = set.size;
1434
- #{rehash}(self);
1435
- /*#{dtor}(&set);*/
1436
- }
1437
- #{define} void #{xor?}(#{type}* self, #{type}* other) {
1438
- #{it} it;
1439
- #{type} set;
1440
- #{assert}(self);
1441
- #{assert}(other);
1442
- #{ctor}(&set);
1443
- #{itCtor}(&it, self);
1444
- while(#{itHasNext}(&it)) {
1445
- #{element.type} element = #{itNext}(&it);
1446
- if(!#{contains}(other, element)) #{put}(&set, element);
1447
- }
1448
- #{itCtor}(&it, other);
1449
- while(#{itHasNext}(&it)) {
1450
- #{element.type} element = #{itNext}(&it);
1451
- if(!#{contains}(self, element)) #{put}(&set, element);
1452
- }
1453
- #{dtor}(self);
1454
- self->buckets = set.buckets;
1455
- self->size = set.size;
1456
- #{rehash}(self);
1457
- /*#{dtor}(&set);*/
1458
- }
1459
- #{define} void #{itCtor}(#{it}* self, #{type}* set) {
1460
- #{assert}(self);
1461
- self->set = set;
1462
- self->bucket_index = 0;
1463
- #{@list.itCtor}(&self->it, &set->buckets[0]);
1464
- }
1465
- #{define} int #{itHasNext}(#{it}* self) {
1466
- #{assert}(self);
1467
- if(#{@list.itHasNext}(&self->it)) {
1468
- return 1;
1469
- } else {
1470
- size_t i; for(i = self->bucket_index+1; i < self->set->bucket_count; ++i) {
1471
- if(!#{@list.empty}(&self->set->buckets[i])) {
1472
- return 1;
1473
- }
1474
- }
1475
- return 0;
1476
- }
1477
- }
1478
- #{define} #{element.type} #{itNext}(#{it}* self) {
1479
- #{assert}(self);
1480
- #{assert}(#{itHasNext}(self));
1481
- if(#{@list.itHasNext}(&self->it)) {
1482
- return #{@list.itNext}(&self->it);
1483
- } else {
1484
- size_t i; for(i = self->bucket_index+1; i < self->set->bucket_count; ++i) {
1485
- if(!#{@list.empty}(&self->set->buckets[i])) {
1486
- #{@list.itCtor}(&self->it, &self->set->buckets[i]);
1487
- self->bucket_index = i;
1488
- return #{@list.itNext}(&self->it);
1489
- }
1490
- }
1491
- #{abort}();
1492
- }
1493
- }
1494
- $
1495
- stream << %$
1496
- #{define} void #{dumpStats}(#{type}* self, FILE* file) {
1497
- size_t index, min_size, max_size;
1498
- #{assert}(self);
1499
- #{assert}(file);
1500
- min_size = self->size;
1501
- max_size = 0;
1502
- fprintf(file, "element count = %d\\n", self->size);
1503
- fprintf(file, "bucket count = %d\\n", self->bucket_count);
1504
- for(index = 0; index < self->bucket_count; ++index) {
1505
- size_t bucket_size = #{@list.size}(&self->buckets[index]);
1506
- if(min_size > bucket_size) min_size = bucket_size;
1507
- if(max_size < bucket_size) max_size = bucket_size;
1508
- fprintf(file, "[%d] element count = %d (%.1f%%)\\n", index, bucket_size, (double)bucket_size*100/self->size);
1509
- }
1510
- fprintf(file, "element count = [%d ... %d]\\n", min_size, max_size);
1511
- }
1512
- $ if $debug
1513
- end
1514
- protected
1515
- # :nodoc:
1516
- class ElementType < DataStructBuilder::Type
1517
- include Assignable, Destructible, Hashable, EqualityTestable
1518
- end # ElementType
1519
- # :nodoc:
1520
- def new_element_type(hash)
1521
- @element_hash = hash
1522
- ElementType.new(hash)
1523
- end
1524
- # :nodoc:
1525
- def new_list
1526
- List.new("#{type}List", @element_hash)
1527
- end
1528
- end # Set
1529
-
1530
-
1531
- =begin rdoc
1532
- Data structure representing hashed map.
1533
- =end
1534
- class HashMap < Code
1535
- include Writers
1536
- attr_reader :key, :value
1537
- # :nodoc:
1538
- def entities; [PrologueCode, @key.code, @value.code, @entry.code].compact end
1539
- # :nodoc:
1540
- def initialize(type, key_descriptor, value_descriptor, visibility = :public)
1541
- super(type, visibility)
1542
- @entry_hash = {:type=>entry, :hash=>entryHash, :equal=>entryEqual, :assign=>entryAssign, :dtor=>entryDtor}
1543
- @entry = new_entry_type
1544
- @entry_set = new_entry_set
1545
- @key = new_key_type(key_descriptor)
1546
- @value = new_value_type(value_descriptor)
1547
- @self_hash = {:type=>"#{type}*", :assign=>assign, :ctor=>new, :dtor=>destroy}
1548
- end
1549
- # :nodoc:
1550
- def [](symbol)
1551
- @self_hash[symbol]
1552
- end
1553
- # :nodoc:
1554
- def write_intf(stream)
1555
- key.write_intf(stream)
1556
- value.write_intf(stream)
1557
- super
1558
- end
1559
- # :nodoc:
1560
- def write_exported_types(stream)
1561
- stream << %$
1562
- typedef struct #{@entry.type} #{@entry.type};
1563
- struct #{@entry.type} {
1564
- #{key.type} key;
1565
- #{value.type} value;
1566
- int valid_value;
1567
- };
1568
- $
1569
- @entry_set.write_exported_types(stream)
1570
- stream << %$
1571
- typedef struct #{type} #{type};
1572
- typedef struct #{it} #{it};
1573
- struct #{type} {
1574
- #{@entry_set.type} entries;
1575
- size_t ref_count;
1576
- };
1577
- struct #{it} {
1578
- #{@entry_set.it} it;
1579
- };
1580
- $
1581
- end
1582
- # :nodoc:
1583
- def write_exported_declarations(stream, declare, define)
1584
- stream << %$
1585
- #{declare} void #{ctor}(#{type}*);
1586
- #{declare} void #{dtor}(#{type}*);
1587
- #{declare} #{type}* #{new}(void);
1588
- #{declare} void #{destroy}(#{type}*);
1589
- #{declare} #{type}* #{assign}(#{type}*);
1590
- #{declare} void #{purge}(#{type}*);
1591
- #{declare} void #{rehash}(#{type}*);
1592
- #{declare} size_t #{size}(#{type}*);
1593
- #{declare} int #{empty}(#{type}*);
1594
- #{declare} int #{containsKey}(#{type}*, #{key.type});
1595
- #{declare} #{value.type} #{get}(#{type}*, #{key.type});
1596
- #{declare} int #{put}(#{type}*, #{key.type}, #{value.type});
1597
- #{declare} void #{replace}(#{type}*, #{key.type}, #{value.type});
1598
- #{declare} int #{remove}(#{type}*, #{key.type});
1599
- #{declare} void #{itCtor}(#{it}*, #{type}*);
1600
- #{declare} int #{itHasNext}(#{it}*);
1601
- #{declare} #{key.type} #{itNextKey}(#{it}*);
1602
- #{declare} #{value.type} #{itNextValue}(#{it}*);
1603
- #{declare} #{@entry.type} #{itNext}(#{it}*);
1604
- $
1605
- stream << %$#{declare} void #{dumpStats}(#{type}*, FILE*);$ if $debug
1606
-
1607
- end
1608
- # :nodoc:
1609
- def write_implementations(stream, define)
1610
- stream << %$
1611
- static #{@entry.type} #{entryKeyOnly}(#{key.type} key) {
1612
- #{@entry.type} entry;
1613
- entry.key = key;
1614
- entry.valid_value = 0;
1615
- return entry;
1616
- }
1617
- static #{@entry.type} #{entryKeyValue}(#{key.type} key, #{value.type} value) {
1618
- #{@entry.type} entry;
1619
- entry.key = key;
1620
- entry.value = value;
1621
- entry.valid_value = 1;
1622
- return entry;
1623
- }
1624
- static size_t #{entryHash}(#{@entry.type} entry) {
1625
- return #{key.hash("entry.key")};
1626
- }
1627
- static int #{entryEqual}(#{@entry.type} lt, #{@entry.type} rt) {
1628
- return #{key.equal("lt.key", "rt.key")};
1629
- }
1630
- static #{@entry.type} #{entryAssign}(#{@entry.type} entry) {
1631
- entry.key = #{key.assign("entry.key")};
1632
- if(entry.valid_value) entry.value = #{value.assign("entry.value")};
1633
- return entry;
1634
- }
1635
- static void #{entryDtor}(#{@entry.type} entry) {
1636
- #{key.dtor("entry.key")};
1637
- if(entry.valid_value) #{value.dtor("entry.value")};
1638
- }
1639
- $
1640
- @entry_set.write_exported_declarations(stream, static, inline)
1641
- @entry_set.write_implementations(stream, static)
1642
- stream << %$
1643
- #{define} void #{ctor}(#{type}* self) {
1644
- #{assert}(self);
1645
- #{@entry_set.ctor}(&self->entries);
1646
- }
1647
- #{define} void #{dtor}(#{type}* self) {
1648
- #{assert}(self);
1649
- #{@entry_set.dtor}(&self->entries);
1650
- }
1651
- #{define} #{type}* #{new}(void) {
1652
- #{type}* self = (#{type}*)#{malloc}(sizeof(#{type})); #{assert}(self);
1653
- #{ctor}(self);
1654
- self->ref_count = 0;
1655
- return self;
1656
- }
1657
- #{define} void #{destroy}(#{type}* self) {
1658
- #{assert}(self);
1659
- if(!--self->ref_count) {
1660
- #{dtor}(self);
1661
- #{free}(self);
1662
- }
1663
- }
1664
- #{define} void #{rehash}(#{type}* self) {
1665
- #{assert}(self);
1666
- #{@entry_set.rehash}(&self->entries);
1667
- }
1668
- #{define} #{type}* #{assign}(#{type}* self) {
1669
- #{assert}(self);
1670
- ++self->ref_count;
1671
- return self;
1672
- }
1673
- #{define} void #{purge}(#{type}* self) {
1674
- #{assert}(self);
1675
- #{@entry_set.purge}(&self->entries);
1676
- }
1677
- #{define} size_t #{size}(#{type}* self) {
1678
- #{assert}(self);
1679
- return #{@entry_set.size}(&self->entries);
1680
- }
1681
- #{define} int #{empty}(#{type}* self) {
1682
- #{assert}(self);
1683
- return #{@entry_set.empty}(&self->entries);
1684
- }
1685
- #{define} int #{containsKey}(#{type}* self, #{key.type} key) {
1686
- int result;
1687
- #{@entry.type} entry;
1688
- #{assert}(self);
1689
- entry = #{@entry.assign("#{entryKeyOnly}(key)")};
1690
- result = #{@entry_set.contains}(&self->entries, entry);
1691
- #{@entry.dtor("entry")};
1692
- return result;
1693
- }
1694
- #{define} #{value.type} #{get}(#{type}* self, #{key.type} key) {
1695
- #{value.type} result;
1696
- #{@entry.type} entry;
1697
- #{assert}(self);
1698
- entry = #{@entry.assign("#{entryKeyOnly}(key)")};
1699
- #{assert}(#{containsKey}(self, key));
1700
- result = #{@entry_set.get}(&self->entries, entry).value;
1701
- #{@entry.dtor("entry")};
1702
- return result;
1703
- }
1704
- #{define} int #{put}(#{type}* self, #{key.type} key, #{value.type} value) {
1705
- #{@entry.type} entry = #{@entry.assign("#{entryKeyValue}(key,value)")};
1706
- #{assert}(self);
1707
- if(!#{containsKey}(self, key)) {
1708
- #{@entry_set.put}(&self->entries, entry);
1709
- #{@entry.dtor("entry")};
1710
- return 1;
1711
- } else {
1712
- #{@entry.dtor("entry")};
1713
- return 0;
1714
- }
1715
- }
1716
- #{define} void #{replace}(#{type}* self, #{key.type} key, #{value.type} value) {
1717
- #{@entry.type} entry;
1718
- #{assert}(self);
1719
- entry = #{@entry.assign("#{entryKeyValue}(key,value)")};
1720
- #{@entry_set.replace}(&self->entries, entry);
1721
- #{@entry.dtor("entry")};
1722
- }
1723
- #{define} int #{remove}(#{type}* self, #{key.type} key) {
1724
- int removed;
1725
- #{@entry.type} entry;
1726
- #{assert}(self);
1727
- entry = #{@entry.assign("#{entryKeyOnly}(key)")};
1728
- removed = #{@entry_set.remove}(&self->entries, entry);
1729
- #{@entry.dtor("entry")};
1730
- return removed;
1731
- }
1732
- #{define} void #{itCtor}(#{it}* self, #{type}* map) {
1733
- #{assert}(self);
1734
- #{assert}(map);
1735
- #{@entry_set.itCtor}(&self->it, &map->entries);
1736
- }
1737
- #{define} int #{itHasNext}(#{it}* self) {
1738
- #{assert}(self);
1739
- return #{@entry_set.itHasNext}(&self->it);
1740
- }
1741
- #{define} #{key.type} #{itNextKey}(#{it}* self) {
1742
- #{assert}(self);
1743
- return #{@entry_set.itNext}(&self->it).key;
1744
- }
1745
- #{define} #{value.type} #{itNextValue}(#{it}* self) {
1746
- #{assert}(self);
1747
- return #{@entry_set.itNext}(&self->it).value;
1748
- }
1749
- #{define} #{@entry.type} #{itNext}(#{it}* self) {
1750
- #{assert}(self);
1751
- return #{@entry_set.itNext}(&self->it);
1752
- }
1753
- $
1754
- stream << %$
1755
- #{define} void #{dumpStats}(#{type}* self, FILE* file) {
1756
- #{assert}(self);
1757
- #{assert}(file);
1758
- #{@entry_set.dumpStats}(&self->entries, file);
1759
- }
1760
- $ if $debug
1761
- end
1762
- protected
1763
- # :nodoc:
1764
- class EntryType < DataStructBuilder::Type
1765
- include Assignable, Destructible, Hashable, EqualityTestable
1766
- end # EntryType
1767
- # :nodoc:
1768
- class KeyType < DataStructBuilder::Type
1769
- include Assignable, Destructible, Hashable, EqualityTestable
1770
- end # KeyType
1771
- # :nodoc:
1772
- class ValueType < DataStructBuilder::Type
1773
- include Assignable, Destructible
1774
- end # ValueType
1775
- # :nodoc:
1776
- def new_entry_type
1777
- EntryType.new(@entry_hash)
1778
- end
1779
- # :nodoc:
1780
- def new_key_type(type)
1781
- KeyType.new(type)
1782
- end
1783
- # :nodoc:
1784
- def new_value_type(type)
1785
- ValueType.new(type)
1786
- end
1787
- # :nodoc:
1788
- def new_entry_set
1789
- HashSet.new("#{type}Set", @entry_hash)
1790
- end
1791
- end # Map
1792
-
1793
-
1794
- end # DataStructBuilder