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.
- checksums.yaml +4 -4
- data/CHANGES +4 -0
- data/doc/AutoC.html +55 -55
- data/doc/AutoC/Code.html +60 -57
- data/doc/AutoC/Collection.html +134 -124
- data/doc/AutoC/HashMap.html +147 -185
- data/doc/AutoC/HashSet.html +114 -325
- data/doc/AutoC/Iterators.html +126 -0
- data/doc/AutoC/Iterators/Bidirectional.html +204 -0
- data/doc/AutoC/Iterators/Unidirectional.html +200 -0
- data/doc/AutoC/List.html +81 -76
- data/doc/AutoC/Maps.html +290 -0
- data/doc/AutoC/Module.html +72 -69
- data/doc/AutoC/Module/File.html +55 -52
- data/doc/AutoC/Module/Header.html +55 -52
- data/doc/AutoC/Module/Source.html +63 -60
- data/doc/AutoC/Priority.html +57 -57
- data/doc/AutoC/Queue.html +75 -74
- data/doc/AutoC/Reference.html +92 -91
- data/doc/AutoC/Sets.html +520 -0
- data/doc/AutoC/String.html +70 -69
- data/doc/AutoC/TreeMap.html +1565 -0
- data/doc/AutoC/TreeSet.html +1447 -0
- data/doc/AutoC/Type.html +184 -110
- data/doc/AutoC/UserDefinedType.html +102 -102
- data/doc/AutoC/Vector.html +100 -91
- data/doc/_index.html +97 -33
- data/doc/class_list.html +24 -31
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +220 -78
- data/doc/file.CHANGES.html +37 -30
- data/doc/file.README.html +29 -30
- data/doc/file_list.html +29 -31
- data/doc/frames.html +7 -16
- data/doc/index.html +29 -30
- data/doc/js/app.js +100 -76
- data/doc/js/full_list.js +170 -135
- data/doc/method_list.html +877 -431
- data/doc/top-level-namespace.html +35 -35
- data/lib/autoc.rb +4 -2
- data/lib/autoc/collection.rb +10 -4
- data/lib/autoc/collection/hash_map.rb +22 -41
- data/lib/autoc/collection/hash_set.rb +13 -120
- data/lib/autoc/collection/iterator.rb +39 -0
- data/lib/autoc/collection/list.rb +7 -5
- data/lib/autoc/collection/map.rb +41 -0
- data/lib/autoc/collection/queue.rb +8 -8
- data/lib/autoc/collection/set.rb +134 -0
- data/lib/autoc/collection/tree_map.rb +464 -0
- data/lib/autoc/collection/tree_set.rb +611 -0
- data/lib/autoc/collection/vector.rb +8 -4
- data/lib/autoc/string.rb +1 -1
- data/lib/autoc/type.rb +3 -0
- data/test/test.rb +2 -2
- data/test/test_auto.c +7141 -0
- data/test/test_auto.h +753 -0
- data/test/test_int_tree_set.rb +111 -0
- data/test/test_value_hash_map.rb +1 -1
- data/test/test_value_hash_set.rb +1 -1
- data/test/test_value_tree_map.rb +176 -0
- data/test/test_value_tree_set.rb +173 -0
- 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}>
|
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}>
|
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}(<, &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}(<, &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
|