autoc 1.3 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -0
  3. data/doc/AutoC.html +55 -55
  4. data/doc/AutoC/Code.html +60 -57
  5. data/doc/AutoC/Collection.html +134 -124
  6. data/doc/AutoC/HashMap.html +147 -185
  7. data/doc/AutoC/HashSet.html +114 -325
  8. data/doc/AutoC/Iterators.html +126 -0
  9. data/doc/AutoC/Iterators/Bidirectional.html +204 -0
  10. data/doc/AutoC/Iterators/Unidirectional.html +200 -0
  11. data/doc/AutoC/List.html +81 -76
  12. data/doc/AutoC/Maps.html +290 -0
  13. data/doc/AutoC/Module.html +72 -69
  14. data/doc/AutoC/Module/File.html +55 -52
  15. data/doc/AutoC/Module/Header.html +55 -52
  16. data/doc/AutoC/Module/Source.html +63 -60
  17. data/doc/AutoC/Priority.html +57 -57
  18. data/doc/AutoC/Queue.html +75 -74
  19. data/doc/AutoC/Reference.html +92 -91
  20. data/doc/AutoC/Sets.html +520 -0
  21. data/doc/AutoC/String.html +70 -69
  22. data/doc/AutoC/TreeMap.html +1565 -0
  23. data/doc/AutoC/TreeSet.html +1447 -0
  24. data/doc/AutoC/Type.html +184 -110
  25. data/doc/AutoC/UserDefinedType.html +102 -102
  26. data/doc/AutoC/Vector.html +100 -91
  27. data/doc/_index.html +97 -33
  28. data/doc/class_list.html +24 -31
  29. data/doc/css/full_list.css +32 -31
  30. data/doc/css/style.css +220 -78
  31. data/doc/file.CHANGES.html +37 -30
  32. data/doc/file.README.html +29 -30
  33. data/doc/file_list.html +29 -31
  34. data/doc/frames.html +7 -16
  35. data/doc/index.html +29 -30
  36. data/doc/js/app.js +100 -76
  37. data/doc/js/full_list.js +170 -135
  38. data/doc/method_list.html +877 -431
  39. data/doc/top-level-namespace.html +35 -35
  40. data/lib/autoc.rb +4 -2
  41. data/lib/autoc/collection.rb +10 -4
  42. data/lib/autoc/collection/hash_map.rb +22 -41
  43. data/lib/autoc/collection/hash_set.rb +13 -120
  44. data/lib/autoc/collection/iterator.rb +39 -0
  45. data/lib/autoc/collection/list.rb +7 -5
  46. data/lib/autoc/collection/map.rb +41 -0
  47. data/lib/autoc/collection/queue.rb +8 -8
  48. data/lib/autoc/collection/set.rb +134 -0
  49. data/lib/autoc/collection/tree_map.rb +464 -0
  50. data/lib/autoc/collection/tree_set.rb +611 -0
  51. data/lib/autoc/collection/vector.rb +8 -4
  52. data/lib/autoc/string.rb +1 -1
  53. data/lib/autoc/type.rb +3 -0
  54. data/test/test.rb +2 -2
  55. data/test/test_auto.c +7141 -0
  56. data/test/test_auto.h +753 -0
  57. data/test/test_int_tree_set.rb +111 -0
  58. data/test/test_value_hash_map.rb +1 -1
  59. data/test/test_value_hash_set.rb +1 -1
  60. data/test/test_value_tree_map.rb +176 -0
  61. data/test/test_value_tree_set.rb +173 -0
  62. metadata +21 -5
@@ -0,0 +1,39 @@
1
+ module AutoC
2
+
3
+
4
+ # :nodoc:
5
+ module Iterators
6
+
7
+
8
+ # :nodoc:
9
+ module Unidirectional
10
+ def write_intf_decls(stream, declare, define)
11
+ super
12
+ stream << %$
13
+ #{declare} void #{itCtor}(#{it_ref}, #{type_ref});
14
+ #{declare} int #{itMove}(#{it_ref});
15
+ #{declare} #{element.type} #{itGet}(#{it_ref});
16
+ $
17
+ end
18
+ end
19
+
20
+
21
+ # :nodoc:
22
+ module Bidirectional
23
+ def write_intf_decls(stream, declare, define)
24
+ super
25
+ stream << %$
26
+ #{declare} void #{itCtor}(#{it_ref}, #{type_ref});
27
+ #define #{itCtor}(self, type) #{itCtorEx}(self, type, 1)
28
+ #{declare} void #{itCtorEx}(#{it_ref}, #{type_ref}, int);
29
+ #{declare} int #{itMove}(#{it_ref});
30
+ #{declare} #{element.type} #{itGet}(#{it_ref});
31
+ $
32
+ end
33
+ end
34
+
35
+
36
+ end # Iterators
37
+
38
+
39
+ end # AutoC
@@ -1,12 +1,15 @@
1
1
  require "autoc/collection"
2
2
 
3
3
 
4
+ require "autoc/collection/iterator"
5
+
6
+
4
7
  module AutoC
5
8
 
6
9
 
7
10
  =begin
8
11
 
9
- List is an ordered unidirectional sequence container.
12
+ List< *_E_* > is an ordered unidirectional sequence container.
10
13
  List supports submission/polling operations on one end hence it can be used as a LIFO container (a stack).
11
14
 
12
15
  The collection's C++ counterpart is +std::forward_list<>+ template class.
@@ -154,11 +157,13 @@ WARNING: current position *must* be valid otherwise the behavior is undefined. S
154
157
  =end
155
158
  class List < Collection
156
159
 
160
+ include Iterators::Unidirectional
161
+
157
162
  def write_intf_types(stream)
158
163
  super
159
164
  stream << %$
160
165
  /***
161
- **** #{type}<#{element.type}> (#{self.class})
166
+ **** #{type}<#{element.type}>
162
167
  ***/
163
168
  $ if public?
164
169
  stream << %$
@@ -203,9 +208,6 @@ class List < Collection
203
208
  #{declare} int #{removeEx}(#{type_ref}, #{element.type}, int);
204
209
  #{declare} size_t #{size}(#{type_ref});
205
210
  #define #{empty}(self) (#{size}(self) == 0)
206
- #{declare} void #{itCtor}(#{it_ref}, #{type_ref});
207
- #{declare} int #{itMove}(#{it_ref});
208
- #{declare} #{element.type} #{itGet}(#{it_ref});
209
211
  $
210
212
  end
211
213
 
@@ -0,0 +1,41 @@
1
+ module AutoC
2
+
3
+ # :nodoc:
4
+ module Maps
5
+
6
+ def write_intf_types(stream)
7
+ super
8
+ stream << %$
9
+ /***
10
+ **** #{type}<#{key.type} -> #{value.type}>
11
+ ***/
12
+ $ if public?
13
+ end
14
+
15
+ def write_intf_decls(stream, declare, define)
16
+ super
17
+ stream << %$
18
+ #{declare} #{ctor.declaration};
19
+ #{declare} #{dtor.declaration};
20
+ #{declare} #{copy.declaration};
21
+ #{declare} #{equal.declaration};
22
+ #{declare} #{identify.declaration};
23
+ #{declare} void #{purge}(#{type_ref});
24
+ #{declare} size_t #{size}(#{type_ref});
25
+ #define #{empty}(self) (#{size}(self) == 0)
26
+ #{declare} int #{containsKey}(#{type_ref}, #{key.type});
27
+ #{declare} #{value.type} #{get}(#{type_ref}, #{key.type});
28
+ #{declare} int #{put}(#{type_ref}, #{key.type}, #{value.type});
29
+ #{declare} int #{replace}(#{type_ref}, #{key.type}, #{value.type});
30
+ #{declare} int #{remove}(#{type_ref}, #{key.type});
31
+ #{declare} int #{itMove}(#{it_ref});
32
+ #{declare} #{key.type} #{itGetKey}(#{it_ref});
33
+ #{declare} #{value.type} #{itGetElement}(#{it_ref});
34
+ #define #{itGet}(it) #{itGetElement}(it)
35
+ $
36
+ end
37
+
38
+ end # Maps
39
+
40
+
41
+ end # AutoC
@@ -1,12 +1,15 @@
1
1
  require "autoc/collection"
2
2
 
3
3
 
4
+ require "autoc/collection/iterator"
5
+
6
+
4
7
  module AutoC
5
8
 
6
9
 
7
10
  =begin
8
11
 
9
- Queue is an ordered bidirectional sequence container.
12
+ Queue< *_E_* > is an ordered bidirectional sequence container.
10
13
  Queue supports addition/removal operations at both ends.
11
14
  However, it is intended to be used as a FIFO container as opposed to {AutoC::List}
12
15
  therefore the default submission, polling and retrieval operations are performed on the opposite ends.
@@ -168,7 +171,7 @@ Return number of elements stored in +self+.
168
171
  |===
169
172
  |*_void_* ~it~Ctor(*_IteratorType_* * +it+, *_Type_* * +self+)
170
173
  |
171
- Create a new forward iterator +it+ on queue +self+.
174
+ Create a new forward (see ~it~CtorEx()) iterator +it+ on queue +self+.
172
175
 
173
176
  NOTE: Previous contents of +it+ is overwritten.
174
177
 
@@ -193,11 +196,13 @@ WARNING: current position *must* be valid otherwise the behavior is undefined. S
193
196
  =end
194
197
  class Queue < Collection
195
198
 
199
+ include Iterators::Bidirectional
200
+
196
201
  def write_intf_types(stream)
197
202
  super
198
203
  stream << %$
199
204
  /***
200
- **** #{type}<#{element.type}> (#{self.class})
205
+ **** #{type}<#{element.type}>
201
206
  ***/
202
207
  $ if public?
203
208
  stream << %$
@@ -250,11 +255,6 @@ class Queue < Collection
250
255
  #{declare} int #{removeEx}(#{type_ref}, #{element.type}, int);
251
256
  #{declare} size_t #{size}(#{type_ref});
252
257
  #define #{empty}(self) (#{size}(self) == 0)
253
- #{declare} void #{itCtor}(#{it_ref}, #{type_ref});
254
- #define #{itCtor}(self, type) #{itCtorEx}(self, type, 1)
255
- #{declare} void #{itCtorEx}(#{it_ref}, #{type_ref}, int);
256
- #{declare} int #{itMove}(#{it_ref});
257
- #{declare} #{element.type} #{itGet}(#{it_ref});
258
258
  $
259
259
  end
260
260
 
@@ -0,0 +1,134 @@
1
+ module AutoC
2
+
3
+
4
+ # :nodoc
5
+ module Sets
6
+
7
+ def write_intf_types(stream)
8
+ super
9
+ stream << %$
10
+ /***
11
+ **** #{type}<#{element.type}>
12
+ ***/
13
+ $ if public?
14
+ end
15
+
16
+ def write_intf_decls(stream, declare, define)
17
+ super
18
+ stream << %$
19
+ #{declare} #{ctor.declaration};
20
+ #{declare} #{dtor.declaration};
21
+ #{declare} #{copy.declaration};
22
+ #{declare} #{equal.declaration};
23
+ #{declare} #{identify.declaration};
24
+ #{declare} void #{purge}(#{type_ref});
25
+ #{declare} int #{contains}(#{type_ref}, #{element.type});
26
+ #{declare} #{element.type} #{get}(#{type_ref}, #{element.type});
27
+ #{declare} size_t #{size}(#{type_ref});
28
+ #define #{empty}(self) (#{size}(self) == 0)
29
+ #{declare} int #{put}(#{type_ref}, #{element.type});
30
+ #{declare} int #{replace}(#{type_ref}, #{element.type});
31
+ #{declare} int #{remove}(#{type_ref}, #{element.type});
32
+ #{declare} void #{exclude}(#{type_ref}, #{type_ref});
33
+ #{declare} void #{retain}(#{type_ref}, #{type_ref});
34
+ #{declare} void #{include}(#{type_ref}, #{type_ref});
35
+ #{declare} void #{invert}(#{type_ref}, #{type_ref});
36
+ $
37
+ end
38
+
39
+ def write_impls(stream, define)
40
+ super
41
+ stream << %$
42
+ static #{element.type_ref} #{itGetRef}(#{it_ref});
43
+ static int #{containsAllOf}(#{type_ref} self, #{type_ref} other) {
44
+ #{it} it;
45
+ #{itCtor}(&it, self);
46
+ while(#{itMove}(&it)) {
47
+ if(!#{contains}(other, *#{itGetRef}(&it))) return 0;
48
+ }
49
+ return 1;
50
+ }
51
+ #{define} #{copy.definition} {
52
+ #{it} it;
53
+ #{assert}(src);
54
+ #{assert}(dst);
55
+ #{ctor}(dst);
56
+ #{itCtor}(&it, src);
57
+ while(#{itMove}(&it)) #{put}(dst, *#{itGetRef}(&it));
58
+ }
59
+ #{define} #{equal.definition} {
60
+ #{assert}(lt);
61
+ #{assert}(rt);
62
+ return #{size}(lt) == #{size}(rt) && #{containsAllOf}(lt, rt) && #{containsAllOf}(rt, lt);
63
+ }
64
+ #{define} #{identify.definition} {
65
+ #{it} it;
66
+ size_t result = 0;
67
+ #{assert}(self);
68
+ #{itCtor}(&it, self);
69
+ while(#{itMove}(&it)) {
70
+ #{element.type}* e = #{itGetRef}(&it);
71
+ result ^= #{element.identify("*e")};
72
+ result = AUTOC_RCYCLE(result);
73
+ }
74
+ return result;
75
+ }
76
+ #{define} size_t #{size}(#{type_ref} self) {
77
+ #{assert}(self);
78
+ return self->size;
79
+ }
80
+ #{define} void #{include}(#{type_ref} self, #{type_ref} other) {
81
+ #{it} it;
82
+ #{assert}(self);
83
+ #{assert}(other);
84
+ #{itCtor}(&it, other);
85
+ while(#{itMove}(&it)) #{put}(self, *#{itGetRef}(&it));
86
+ }
87
+ #{define} void #{retain}(#{type_ref} self, #{type_ref} other) {
88
+ #{it} it;
89
+ #{type} set;
90
+ #{assert}(self);
91
+ #{assert}(other);
92
+ #{ctor}(&set);
93
+ #{itCtor}(&it, self);
94
+ while(#{itMove}(&it)) {
95
+ #{element.type}* e = #{itGetRef}(&it);
96
+ #{assert}(e);
97
+ if(#{contains}(other, *e)) #{put}(&set, *e);
98
+ }
99
+ #{dtor}(self);
100
+ *self = set;
101
+ }
102
+ #{define} void #{invert}(#{type_ref} self, #{type_ref} other) {
103
+ #{it} it;
104
+ #{type} set;
105
+ #{assert}(self);
106
+ #{assert}(other);
107
+ #{ctor}(&set);
108
+ #{itCtor}(&it, self);
109
+ while(#{itMove}(&it)) {
110
+ #{element.type}* e = #{itGetRef}(&it);
111
+ if(!#{contains}(other, *e)) #{put}(&set, *e);
112
+ }
113
+ #{itCtor}(&it, other);
114
+ while(#{itMove}(&it)) {
115
+ #{element.type}* e = #{itGetRef}(&it);
116
+ if(!#{contains}(self, *e)) #{put}(&set, *e);
117
+ }
118
+ #{dtor}(self);
119
+ *self = set;
120
+ }
121
+ #{define} void #{exclude}(#{type_ref} self, #{type_ref} other) {
122
+ #{it} it;
123
+ #{assert}(self);
124
+ #{assert}(other);
125
+ #{itCtor}(&it, other);
126
+ while(#{itMove}(&it)) #{remove}(self, *#{itGetRef}(&it));
127
+ }
128
+ $
129
+ end
130
+
131
+ end # Sets
132
+
133
+
134
+ end # AutoC
@@ -0,0 +1,464 @@
1
+ require "autoc/collection"
2
+ require "autoc/collection/tree_set"
3
+
4
+
5
+ require "autoc/collection/map"
6
+
7
+
8
+ module AutoC
9
+
10
+
11
+ =begin
12
+
13
+ TreeMap< *_K_* => *_E_* > is a tree-based ordered random access container holding unique keys with each key having an element bound to it.
14
+
15
+ TreeMap is backed by {AutoC::TreeSet} container.
16
+
17
+ The collection's C++ counterpart is +std::map<>+ template class.
18
+
19
+ == Generated C interface
20
+
21
+ === Collection management
22
+
23
+ [cols=2*]
24
+ |===
25
+ |*_void_* ~type~Copy(*_Type_* * +dst+, *_Type_* * +src+)
26
+ |
27
+ Create a new map +dst+ filled with the contents of +src+.
28
+ A copy operation is performed on all keys and values in +src+.
29
+
30
+ NOTE: Previous contents of +dst+ is overwritten.
31
+
32
+ |*_void_* ~type~Ctor(*_Type_* * +self+)
33
+ |
34
+ Create a new empty map +self+.
35
+
36
+ NOTE: Previous contents of +self+ is overwritten.
37
+
38
+ |*_void_* ~type~Dtor(*_Type_* * +self+)
39
+ |
40
+ Destroy map +self+.
41
+ Stored keys and values are destroyed as well by calling the respective destructors.
42
+
43
+ |*_int_* ~type~Equal(*_Type_* * +lt+, *_Type_* * +rt+)
44
+ |
45
+ Return non-zero value if maps +lt+ and +rt+ are considered equal by contents and zero value otherwise.
46
+
47
+ |*_size_t_* ~type~Identify(*_Type_* * +self+)
48
+ |
49
+ Return hash code for map +self+.
50
+ |===
51
+
52
+ === Basic operations
53
+
54
+ [cols=2*]
55
+ |===
56
+ |*_int_* ~type~ContainsKey(*_Type_* * +self+, *_K_* +key+)
57
+ |
58
+ Return non-zero value if map +self+ contains an entry with a key considered equal to the key +key+ and zero value otherwise.
59
+
60
+ |*_int_* ~type~Empty(*_Type_* * +self+)
61
+ |
62
+ Return non-zero value if map +self+ contains no entries and zero value otherwise.
63
+
64
+ |*_E_* ~type~Get(*_Type_* * +self+, *_K_* +key+)
65
+ |
66
+ Return a _copy_ of the element in +self+ bound to a key which is considered equal to the key +key+.
67
+
68
+ WARNING: +self+ *must* contain such key otherwise the behavior is undefined. See ~type~ContainsKey().
69
+
70
+ |*_E_* ~type~PeekLowestElement(*_Type_* * +self+)
71
+ |
72
+ Return a _copy_ of an element bound to the lowest key in +self+.
73
+
74
+ WARNING: +self+ *must not* be empty otherwise the behavior is undefined. See ~type~Empty().
75
+
76
+ |*_K_* ~type~PeekLowestKey(*_Type_* * +self+)
77
+ |
78
+ Return a _copy_ of the lowest key in +self+.
79
+
80
+ WARNING: +self+ *must not* be empty otherwise the behavior is undefined. See ~type~Empty().
81
+
82
+ |*_E_* ~type~PeekHighestElement(*_Type_* * +self+)
83
+ |
84
+ Return a _copy_ of an element bound to the highest key in +self+.
85
+
86
+ WARNING: +self+ *must not* be empty otherwise the behavior is undefined. See ~type~Empty().
87
+
88
+ |*_K_* ~type~PeekHighestKey(*_Type_* * +self+)
89
+ |
90
+ Return a _copy_ of the highest key in +self+.
91
+
92
+ WARNING: +self+ *must not* be empty otherwise the behavior is undefined. See ~type~Empty().
93
+
94
+ |*_void_* ~type~Purge(*_Type_* * +self+)
95
+ |
96
+ Remove and destroy all keys and elements stored in +self+.
97
+
98
+ |*_int_* ~type~Put(*_Type_* * +self+, *_K_* +key+, *_E_* +value+)
99
+ |
100
+ Put a _copy_ of the element +value+ bound to a _copy_ of the key +key+ into +self+
101
+ *only if* there is no such key in +self+ which is considered equal to +key+.
102
+
103
+ Return non-zero value on successful put and zero value otherwise.
104
+
105
+ |*_int_* ~type~Replace(*_Type_* * +self+, *_K_* +key+, *_E_* +value+)
106
+ |
107
+ If +self+ contains a key which is considered equal to the key +key+,
108
+ remove and destroy that key along with an element bound to it
109
+ and put a new pair built of the _copies_ of +key+ and +value+,
110
+ otherwise no nothing.
111
+
112
+ Return non-zero value if the replacement was actually performed and zero value otherwise.
113
+
114
+ |*_int_* ~type~Remove(*_Type_* * +self+, *_K_* +key+)
115
+ |
116
+ Remove and destroy a key which is considered equal to the key +key+.
117
+ Destroy an element bound to that key.
118
+
119
+ Return non-zero value on successful key/element pair removal and zero value otherwise.
120
+
121
+ |*_size_t_* ~type~Size(*_Type_* * +self+)
122
+ |
123
+ Return number of key/element pairs stored in +self+.
124
+ |===
125
+
126
+ === Iteration
127
+
128
+ [cols=2*]
129
+ |===
130
+ |*_void_* ~it~Ctor(*_IteratorType_* * +it+, *_Type_* * +self+)
131
+ |
132
+ Create a new ascending iterator +it+ on map +self+. See ~it~CtorEx().
133
+
134
+ NOTE: Previous contents of +it+ is overwritten.
135
+
136
+ |*_void_* ~it~CtorEx(*_IteratorType_* * +it+, *_Type_* * +self+, *_int_* +ascending+)
137
+ |
138
+ Create a new iterator +it+ on map +self+.
139
+ Non-zero value of +ascending+ specifies an ascending (+lowest to highest key traversal+) iterator, zero value specifies a descending (+highest to lowest key traversal+) iterator.
140
+
141
+ NOTE: Previous contents of +it+ is overwritten.
142
+
143
+ |*_int_* ~it~Move(*_IteratorType_* * +it+)
144
+ |
145
+ Advance iterator position of +it+ *and* return non-zero value if new position is valid and zero value otherwise.
146
+
147
+ |*_K_* ~it~GetKey(*_IteratorType_* * +it+)
148
+ |
149
+ Return a _copy_ of the key from a key/value pair pointed to by the iterator +it+.
150
+
151
+ WARNING: current position *must* be valid otherwise the behavior is undefined. See ~it~Move().
152
+
153
+ |*_E_* ~it~GetElement(*_IteratorType_* * +it+)
154
+ |
155
+ Return a _copy_ of the element from a key/element pair pointed to by the iterator +it+.
156
+
157
+ WARNING: current position *must* be valid otherwise the behavior is undefined. See ~it~Move().
158
+
159
+ |*_E_* ~it~Get(*_IteratorType_* * +it+)
160
+ |
161
+ Alias for ~it~GetElement().
162
+ |===
163
+
164
+ =end
165
+ class TreeMap < Collection
166
+
167
+ include Maps
168
+
169
+ attr_reader :key
170
+
171
+ alias :value :element
172
+
173
+ def hash; super ^ key.hash end
174
+
175
+ def ==(other) super && key == other.key end
176
+
177
+ alias :eql? :==
178
+
179
+ def entities; super << key end
180
+
181
+ def initialize(type, key_type, value_type, visibility = :public)
182
+ super(type, value_type, visibility)
183
+ @key = Type.coerce(key_type)
184
+ @entry = UserDefinedType.new(:type => entry, :identify => entryIdentify, :equal => entryEqual, :less => entryLess, :copy => entryCopy, :dtor => entryDtor)
185
+ @set = TreeSet.new(set, @entry, :static)
186
+ element_requirement(value)
187
+ key_requirement(key)
188
+ end
189
+
190
+ def copyable?; super && key.copyable? end
191
+
192
+ def comparable?; super && key.comparable? end
193
+
194
+ def hashable?; super && key.hashable? end
195
+
196
+ def write_intf_types(stream)
197
+ super
198
+ stream << %$
199
+ typedef struct #{@entry.type} #{@entry.type};
200
+ struct #{@entry.type} {
201
+ #{key.type} key;
202
+ #{value.type} value;
203
+ unsigned flags;
204
+ };
205
+ $
206
+ @set.write_intf_types(stream)
207
+ stream << %$
208
+ typedef struct #{type} #{type};
209
+ typedef struct #{it} #{it};
210
+ struct #{type} {
211
+ #{@set.type} entries;
212
+ };
213
+ struct #{it} {
214
+ #{@set.it} it;
215
+ };
216
+ $
217
+ end
218
+
219
+ def write_intf_decls(stream, declare, define)
220
+ super
221
+ stream << %$
222
+ #{declare} #{key.type} #{peekLowestKey}(#{type_ref});
223
+ #{declare} #{value.type} #{peekLowestElement}(#{type_ref});
224
+ #{declare} #{key.type} #{peekHighestKey}(#{type_ref});
225
+ #{declare} #{value.type} #{peekHighestElement}(#{type_ref});
226
+ #define #{itCtor}(self, type) #{itCtorEx}(self, type, 1)
227
+ #{declare} void #{itCtorEx}(#{it_ref}, #{type_ref}, int);
228
+ $
229
+ end
230
+
231
+ def write_impls(stream, define)
232
+ super
233
+ stream << %$
234
+ #define #{validValue} 1
235
+ #define #{validKey} 2
236
+ #define #{ownedValue} 4
237
+ #define #{ownedKey} 8
238
+ static #{@entry.type} #{entryKeyOnlyRef}(#{key.type_ref} key) {
239
+ #{@entry.type} entry;
240
+ entry.key = *key;
241
+ entry.flags = #{validKey};
242
+ return entry;
243
+ }
244
+ static #{@entry.type} #{entryKeyValueRef}(#{key.type_ref} key, #{value.type_ref} value) {
245
+ #{@entry.type} entry;
246
+ entry.key = *key;
247
+ entry.value = *value;
248
+ entry.flags = (#{validKey} | #{validValue});
249
+ return entry;
250
+ }
251
+ #define #{entryEqual}(lt, rt) #{entryEqualRef}(&lt, &rt)
252
+ static int #{entryEqualRef}(#{@entry.type}* lt, #{@entry.type}* rt) {
253
+ return #{key.equal("lt->key", "rt->key")};
254
+ }
255
+ #define #{entryLess}(lt, rt) #{entryLessRef}(&lt, &rt)
256
+ static int #{entryLessRef}(#{@entry.type}* lt, #{@entry.type}* rt) {
257
+ return #{key.less("lt->key", "rt->key")};
258
+ }
259
+ #define #{entryIdentify}(obj) #{entryIdentifyRef}(&obj)
260
+ static size_t #{entryIdentifyRef}(#{@entry.type}* entry) {
261
+ return #{key.identify("entry->key")};
262
+ }
263
+ #define #{entryCopy}(dst, src) #{entryCopyRef}(&dst, &src)
264
+ static void #{entryCopyRef}(#{@entry.type_ref} dst, #{@entry.type_ref} src) {
265
+ #{assert}(src->flags & #{validKey});
266
+ dst->flags = (#{validKey} | #{ownedKey});
267
+ #{key.copy("dst->key", "src->key")};
268
+ if(src->flags & #{validValue}) {
269
+ dst->flags |= (#{validValue} | #{ownedValue});
270
+ #{value.copy("dst->value", "src->value")};
271
+ }
272
+ }
273
+ #define #{entryDtor}(obj) #{entryDtorRef}(&obj)
274
+ static void #{entryDtorRef}(#{@entry.type}* entry) {
275
+ #{assert}(entry->flags & #{validKey});
276
+ if(entry->flags & #{ownedKey}) #{key.dtor("entry->key")};
277
+ if(entry->flags & #{validValue} && entry->flags & #{ownedValue}) #{value.dtor("entry->value")};
278
+ }
279
+ static #{@entry.type_ref} #{itGetEntryRef}(#{it_ref});
280
+ static int #{containsAllOf}(#{type_ref} self, #{type_ref} other) {
281
+ #{it} it;
282
+ #{itCtor}(&it, self);
283
+ while(#{itMove}(&it)) {
284
+ int found = 0;
285
+ #{@entry.type}* e = #{itGetEntryRef}(&it);
286
+ if(#{containsKey}(other, e->key)) {
287
+ #{value.type} other_value = #{get}(other, e->key);
288
+ found = #{value.equal("e->value", "other_value")};
289
+ #{value.dtor("other_value")};
290
+ }
291
+ if(!found) return 0;
292
+ }
293
+ return 1;
294
+ }
295
+ $
296
+ @set.write_intf_decls(stream, static, inline)
297
+ @set.write_impls(stream, static)
298
+ stream << %$
299
+ #{define} #{ctor.definition} {
300
+ #{assert}(self);
301
+ #{@set.ctor}(&self->entries);
302
+ }
303
+ #{define} #{dtor.definition} {
304
+ #{assert}(self);
305
+ #{@set.dtor}(&self->entries);
306
+ }
307
+ static int #{putEntryRef}(#{type_ref} self, #{@entry.type_ref} entry) {
308
+ int absent;
309
+ #{assert}(self);
310
+ #{assert}(entry);
311
+ absent = !#{containsKey}(self, entry->key);
312
+ if(absent) #{@set.put}(&self->entries, *entry);
313
+ return absent;
314
+ }
315
+ #{define} #{copy.definition} {
316
+ #{it} it;
317
+ #{assert}(src);
318
+ #{assert}(dst);
319
+ #{ctor}(dst);
320
+ #{itCtor}(&it, src);
321
+ while(#{itMove}(&it)) {
322
+ #{@entry.type}* e = #{itGetEntryRef}(&it);
323
+ #{putEntryRef}(dst, e);
324
+ }
325
+ }
326
+ #{define} #{equal.definition} {
327
+ #{assert}(lt);
328
+ #{assert}(rt);
329
+ return #{size}(lt) == #{size}(rt) && #{containsAllOf}(lt, rt) && #{containsAllOf}(rt, lt);
330
+ }
331
+ #{define} #{identify.definition} {
332
+ #{assert}(self);
333
+ return #{@set.identify}(&self->entries); /* TODO : make use of the values' hashes */
334
+ }
335
+ #{define} void #{purge}(#{type_ref} self) {
336
+ #{assert}(self);
337
+ #{@set.purge}(&self->entries);
338
+ }
339
+ #{define} size_t #{size}(#{type_ref} self) {
340
+ #{assert}(self);
341
+ return #{@set.size}(&self->entries);
342
+ }
343
+ #{define} int #{containsKey}(#{type_ref} self, #{key.type} key) {
344
+ int result;
345
+ #{@entry.type} entry;
346
+ #{assert}(self);
347
+ result = #{@set.contains}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
348
+ #{@entry.dtor("entry")};
349
+ return result;
350
+ }
351
+ #{define} #{value.type} #{get}(#{type_ref} self, #{key.type} key) {
352
+ #{value.type} result;
353
+ #{@entry.type} entry, existing_entry;
354
+ #{assert}(self);
355
+ #{assert}(#{containsKey}(self, key));
356
+ existing_entry = #{@set.get}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
357
+ #{value.copy("result", "existing_entry.value")};
358
+ #{@entry.dtor("existing_entry")};
359
+ #{@entry.dtor("entry")};
360
+ return result;
361
+ }
362
+ #{define} #{key.type} #{peekLowestKey}(#{type_ref} self) {
363
+ #{key.type} result;
364
+ #{@set.node}* node;
365
+ #{assert}(self);
366
+ #{assert}(!#{empty}(self));
367
+ node = #{@set.lowestNode}(&self->entries);
368
+ #{assert}(node);
369
+ #{key.copy("result", "node->element.key")};
370
+ return result;
371
+ }
372
+ #{define} #{value.type} #{peekLowestElement}(#{type_ref} self) {
373
+ #{value.type} result;
374
+ #{@set.node}* node;
375
+ #{assert}(self);
376
+ #{assert}(!#{empty}(self));
377
+ node = #{@set.lowestNode}(&self->entries);
378
+ #{assert}(node);
379
+ #{element.copy("result", "node->element.value")};
380
+ return result;
381
+ }
382
+ #{define} #{key.type} #{peekHighestKey}(#{type_ref} self) {
383
+ #{key.type} result;
384
+ #{@set.node}* node;
385
+ #{assert}(self);
386
+ #{assert}(!#{empty}(self));
387
+ node = #{@set.highestNode}(&self->entries);
388
+ #{assert}(node);
389
+ #{key.copy("result", "node->element.key")};
390
+ return result;
391
+ }
392
+ #{define} #{value.type} #{peekHighestElement}(#{type_ref} self) {
393
+ #{value.type} result;
394
+ #{@set.node}* node;
395
+ #{assert}(self);
396
+ #{assert}(!#{empty}(self));
397
+ node = #{@set.highestNode}(&self->entries);
398
+ #{assert}(node);
399
+ #{element.copy("result", "node->element.value")};
400
+ return result;
401
+ }
402
+ #{define} int #{put}(#{type_ref} self, #{key.type} key, #{value.type} value) {
403
+ int result;
404
+ #{@entry.type} entry;
405
+ #{assert}(self);
406
+ entry = #{entryKeyValueRef}(&key, &value);
407
+ result = #{putEntryRef}(self, &entry);
408
+ #{@entry.dtor("entry")};
409
+ return result;
410
+ }
411
+ #{define} int #{replace}(#{type_ref} self, #{key.type} key, #{value.type} value) {
412
+ int result;
413
+ #{@entry.type} entry;
414
+ #{assert}(self);
415
+ entry = #{entryKeyValueRef}(&key, &value);
416
+ result = #{@set.replace}(&self->entries, entry);
417
+ #{@entry.dtor("entry")};
418
+ return result;
419
+ }
420
+ #{define} int #{remove}(#{type_ref} self, #{key.type} key) {
421
+ int result;
422
+ #{@entry.type} entry;
423
+ #{assert}(self);
424
+ result = #{@set.remove}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
425
+ #{@entry.dtor("entry")};
426
+ return result;
427
+ }
428
+ #{define} void #{itCtorEx}(#{it_ref} self, #{type_ref} map, int ascending) {
429
+ #{assert}(self);
430
+ #{assert}(map);
431
+ #{@set.itCtorEx}(&self->it, &map->entries, ascending);
432
+ }
433
+ #{define} int #{itMove}(#{it_ref} self) {
434
+ #{assert}(self);
435
+ return #{@set.itMove}(&self->it);
436
+ }
437
+ #{define} #{key.type} #{itGetKey}(#{it_ref} self) {
438
+ #{@entry.type_ref} e;
439
+ #{key.type} key;
440
+ #{assert}(self);
441
+ e = #{itGetEntryRef}(self);
442
+ #{key.copy("key", "e->key")};
443
+ return key;
444
+ }
445
+ #{define} #{value.type} #{itGetElement}(#{it_ref} self) {
446
+ #{@entry.type_ref} e;
447
+ #{value.type} value;
448
+ #{assert}(self);
449
+ e = #{itGetEntryRef}(self);
450
+ #{assert}(e->flags & #{validValue});
451
+ #{value.copy("value", "e->value")};
452
+ return value;
453
+ }
454
+ static #{@entry.type_ref} #{itGetEntryRef}(#{it_ref} self) {
455
+ #{assert}(self);
456
+ return #{@set.itGetRef}(&self->it);
457
+ }
458
+ $
459
+ end
460
+
461
+ end # TreeMap
462
+
463
+
464
+ end # AutoC