autoc 1.3 → 1.4

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 (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