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.
- checksums.yaml +7 -0
- data/README +15 -4
- data/doc/AutoC.html +245 -0
- data/doc/AutoC/Code.html +520 -0
- data/doc/AutoC/Collection.html +923 -0
- data/doc/AutoC/HashMap.html +1161 -0
- data/doc/AutoC/HashSet.html +1122 -0
- data/doc/AutoC/List.html +1002 -0
- data/doc/AutoC/Module.html +951 -0
- data/doc/AutoC/Module/File.html +412 -0
- data/doc/AutoC/Module/Header.html +432 -0
- data/doc/AutoC/Module/Source.html +704 -0
- data/doc/AutoC/Priority.html +138 -0
- data/doc/AutoC/Queue.html +1167 -0
- data/doc/AutoC/Type.html +1152 -0
- data/doc/AutoC/UserDefinedType.html +655 -0
- data/doc/AutoC/Vector.html +856 -0
- data/doc/_index.html +299 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +339 -0
- data/doc/file.README.html +112 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +26 -0
- data/doc/index.html +112 -0
- data/doc/js/app.js +219 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +605 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/autoc.rb +35 -12
- data/lib/autoc/{code_builder.rb → code.rb} +230 -247
- data/lib/autoc/collection.rb +137 -0
- data/lib/autoc/collection/hash_map.rb +388 -0
- data/lib/autoc/collection/hash_set.rb +433 -0
- data/lib/autoc/collection/list.rb +410 -0
- data/lib/autoc/collection/queue.rb +514 -0
- data/lib/autoc/collection/vector.rb +295 -0
- data/lib/autoc/type.rb +198 -0
- data/test/test.c +921 -396
- data/test/test.h +41 -0
- data/test/test.rb +21 -26
- data/test/test_auto.c +2630 -3961
- data/test/test_auto.h +449 -560
- metadata +50 -17
- data/lib/autoc/data_struct_builder.rb +0 -1794
- data/lib/autoc/type_builder.rb +0 -24
- data/manual/manual.pdf +0 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
require "autoc/code"
|
2
|
+
require "autoc/type"
|
3
|
+
|
4
|
+
|
5
|
+
module AutoC
|
6
|
+
|
7
|
+
|
8
|
+
=begin
|
9
|
+
|
10
|
+
== Implemented collections
|
11
|
+
|
12
|
+
- {AutoC::Vector} a fixed-sized array
|
13
|
+
|
14
|
+
- {AutoC::List} a single linked list
|
15
|
+
|
16
|
+
- {AutoC::Queue} a double linked list
|
17
|
+
|
18
|
+
- {AutoC::HashSet} a hash-based set
|
19
|
+
|
20
|
+
- {AutoC::HashMap} a hash-based map
|
21
|
+
|
22
|
+
== Ruby side operation
|
23
|
+
|
24
|
+
.Complete example for generation of a list of integers collection:
|
25
|
+
[source,ruby]
|
26
|
+
----
|
27
|
+
require "autoc"
|
28
|
+
AutoC::Module.generate!(:Test) do |c|
|
29
|
+
c << AutoC::List.new(:IntList, :int)
|
30
|
+
end
|
31
|
+
----
|
32
|
+
In the above example a C module Test represented by the C header +test_auto.h+ and the C source +test_auto.c+ are generated.
|
33
|
+
The C++ counterpart of the generated collection is +std::forward_list<int>+.
|
34
|
+
|
35
|
+
== C interface
|
36
|
+
|
37
|
+
=== Element types: values, references
|
38
|
+
|
39
|
+
=== Thread safety
|
40
|
+
|
41
|
+
WARNING: In its current state the implemented collections are *not* thread-safe.
|
42
|
+
|
43
|
+
=== Iteration
|
44
|
+
|
45
|
+
At the moment a fairly simple iteration functionality is implemented.
|
46
|
+
The iterators are modeled after the C# language.
|
47
|
+
All implemented iterators do not require destruction after use.
|
48
|
+
|
49
|
+
.Basic iterator usage example:
|
50
|
+
[source,c]
|
51
|
+
----
|
52
|
+
MyVector c;
|
53
|
+
MyVectorIt it;
|
54
|
+
...
|
55
|
+
MyVectorItCtor(&it, &c);
|
56
|
+
while(MyVectorItMove(&it)) {
|
57
|
+
Element e = MyVectorItGet(&it);
|
58
|
+
...
|
59
|
+
ElementDtor(e);
|
60
|
+
}
|
61
|
+
----
|
62
|
+
|
63
|
+
WARNING: the collection being iterated *must not* be modified in any way otherwise the iterator behavior is undefined.
|
64
|
+
=end
|
65
|
+
class Collection < Type
|
66
|
+
|
67
|
+
def self.coerce(type)
|
68
|
+
type.is_a?(Type) ? type : UserDefinedType.new(type)
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :element
|
72
|
+
|
73
|
+
def entities; super + [element] end
|
74
|
+
|
75
|
+
def initialize(type_name, element_type, visibility = :public)
|
76
|
+
super(type_name, visibility)
|
77
|
+
@element = Collection.coerce(element_type)
|
78
|
+
end
|
79
|
+
|
80
|
+
def ctor(*args)
|
81
|
+
if args.empty?
|
82
|
+
super()
|
83
|
+
else
|
84
|
+
check_args(args, 1)
|
85
|
+
obj = args.first
|
86
|
+
super() + "(&#{obj})"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def dtor(*args)
|
91
|
+
if args.empty?
|
92
|
+
super()
|
93
|
+
else
|
94
|
+
check_args(args, 1)
|
95
|
+
obj = args.first
|
96
|
+
super() + "(&#{obj})"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def copy(*args)
|
101
|
+
if args.empty?
|
102
|
+
super()
|
103
|
+
else
|
104
|
+
check_args(args, 2)
|
105
|
+
dst, src = args
|
106
|
+
super() + "(&#{dst}, &#{src})"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def equal(*args)
|
111
|
+
if args.empty?
|
112
|
+
super()
|
113
|
+
else
|
114
|
+
check_args(args, 2)
|
115
|
+
lt, rt = args
|
116
|
+
super() + "(&#{lt}, &#{rt})"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def less(*args)
|
121
|
+
args.empty? ? super() : raise("#{self.class} provides no ordering functionality")
|
122
|
+
end
|
123
|
+
|
124
|
+
def identify(*args)
|
125
|
+
args.empty? ? super() : raise("#{self.class} provides no hashing functionality")
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def check_args(args, nargs)
|
131
|
+
raise "expected exactly #{nargs} argument(s)" unless args.size == nargs
|
132
|
+
end
|
133
|
+
|
134
|
+
end # Collection
|
135
|
+
|
136
|
+
|
137
|
+
end # AutoC
|
@@ -0,0 +1,388 @@
|
|
1
|
+
require "autoc/collection"
|
2
|
+
require "autoc/collection/hash_set"
|
3
|
+
|
4
|
+
|
5
|
+
module AutoC
|
6
|
+
|
7
|
+
|
8
|
+
=begin
|
9
|
+
|
10
|
+
HashSet is a hash-based unordered random access container holding unique keys with each key having an element bound to it.
|
11
|
+
|
12
|
+
The collection's C++ counterpart is +std::unordered_map<>+ template class.
|
13
|
+
|
14
|
+
== Generated C interface
|
15
|
+
|
16
|
+
=== Collection management
|
17
|
+
|
18
|
+
[cols=2*]
|
19
|
+
|===
|
20
|
+
|*_void_* ~type~Copy(*_Type_* * +dst+, *_Type_* * +src+)
|
21
|
+
|
|
22
|
+
Create a new map +dst+ filled with the contents of +src+.
|
23
|
+
A copy operation is performed on all keys and values in +src+.
|
24
|
+
|
25
|
+
NOTE: Previous contents of +dst+ is overwritten.
|
26
|
+
|
27
|
+
|*_void_* ~type~Ctor(*_Type_* * +self+)
|
28
|
+
|
|
29
|
+
Create a new empty map +self+.
|
30
|
+
|
31
|
+
NOTE: Previous contents of +self+ is overwritten.
|
32
|
+
|
33
|
+
|*_void_* ~type~Dtor(*_Type_* * +self+)
|
34
|
+
|
|
35
|
+
Destroy map +self+.
|
36
|
+
Stored keys and values are destroyed as well by calling the respective destructors.
|
37
|
+
|
38
|
+
|*_int_* ~type~Equal(*_Type_* * +lt+, *_Type_* * +rt+)
|
39
|
+
|
|
40
|
+
Return non-zero value if maps +lt+ and +rt+ are considered equal by contents and zero value otherwise.
|
41
|
+
|
42
|
+
|*_size_t_* ~type~Identify(*_Type_* * +self+)
|
43
|
+
|
|
44
|
+
Return hash code for map +self+.
|
45
|
+
|===
|
46
|
+
|
47
|
+
=== Basic operations
|
48
|
+
|
49
|
+
[cols=2*]
|
50
|
+
|===
|
51
|
+
|*_int_* ~type~ContainsKey(*_Type_* * +self+, *_K_* +key+)
|
52
|
+
|
|
53
|
+
Return non-zero value if map +self+ contains an entry with a key considered equal to the key +key+ and zero value otherwise.
|
54
|
+
|
55
|
+
|*_int_* ~type~Empty(*_Type_* * +self+)
|
56
|
+
|
|
57
|
+
Return non-zero value if map +self+ contains no entries and zero value otherwise.
|
58
|
+
|
59
|
+
|*_E_* ~type~Get(*_Type_* * +self+, *_K_* +key+)
|
60
|
+
|
|
61
|
+
Return a _copy_ of the element in +self+ bound to a key which is considered equal to the key +key+.
|
62
|
+
|
63
|
+
WARNING: +self+ *must* contain such key otherwise the behavior is undefined. See ~type~Contains().
|
64
|
+
|
65
|
+
|*_void_* ~type~Purge(*_Type_* * +self+)
|
66
|
+
|
|
67
|
+
Remove and destroy all keys and elements stored in +self+.
|
68
|
+
|
69
|
+
|*_int_* ~type~Put(*_Type_* * +self+, *_K_* +key+, *_E_* +value+)
|
70
|
+
|
|
71
|
+
Put a _copy_ of the element +value+ bound to a _copy_ of the key +key+ into +self+ *only if* there is no such key in +self+ which is considered equal to +key+.
|
72
|
+
|
73
|
+
Return non-zero value on successful put and zero value otherwise.
|
74
|
+
|
75
|
+
|*_int_* ~type~Replace(*_Type_* * +self+, *_K_* +key+, *_E_* +value+)
|
76
|
+
|
|
77
|
+
If +self+ contains a key which is considered equal to the key +key+,
|
78
|
+
remove and destroy that key along with an element bound to it
|
79
|
+
and put a new pair built of the _copies_ of +key+ and +value+,
|
80
|
+
otherwise simply put a new key/element pair into +self+ in the way of ~type~Put().
|
81
|
+
|
82
|
+
Return non-zero value if the replacement was actually performed and zero value otherwise.
|
83
|
+
|
84
|
+
|*_int_* ~type~Remove(*_Type_* * +self+, *_K_* +key+)
|
85
|
+
|
|
86
|
+
Remove and destroy a key which is considered equal to the key +key+.
|
87
|
+
Destroy an element bound to that key.
|
88
|
+
|
89
|
+
Return non-zero value on successful key/element pair removal and zero value otherwise.
|
90
|
+
|
91
|
+
|*_size_t_* ~type~Size(*_Type_* * +self+)
|
92
|
+
|
|
93
|
+
Return number of key/element pairs stored in +self+.
|
94
|
+
|===
|
95
|
+
|
96
|
+
=== Iteration
|
97
|
+
|
98
|
+
[cols=2*]
|
99
|
+
|===
|
100
|
+
|*_void_* ~it~Ctor(*_IteratorType_* * +it+, *_Type_* * +self+)
|
101
|
+
|
|
102
|
+
Create a new iterator +it+ on map +self+.
|
103
|
+
|
104
|
+
NOTE: As the map is an unordered sequence, the traversal order is unspecified.
|
105
|
+
|
106
|
+
NOTE: Previous contents of +it+ is overwritten.
|
107
|
+
|
108
|
+
|*_int_* ~it~Move(*_IteratorType_* * +it+)
|
109
|
+
|
|
110
|
+
Advance iterator position of +it+ *and* return non-zero value if new position is valid and zero value otherwise.
|
111
|
+
|
112
|
+
|*_K_* ~it~GetKey(*_IteratorType_* * +it+)
|
113
|
+
|
|
114
|
+
Return a _copy_ of the key from a key/value pair pointed to by the iterator +it+.
|
115
|
+
|
116
|
+
WARNING: current position *must* be valid otherwise the behavior is undefined. See ~it~Move().
|
117
|
+
|
118
|
+
|*_E_* ~it~GetElement(*_IteratorType_* * +it+)
|
119
|
+
|
|
120
|
+
Return a _copy_ of the element from a key/element pair pointed to by the iterator +it+.
|
121
|
+
|
122
|
+
WARNING: current position *must* be valid otherwise the behavior is undefined. See ~it~Move().
|
123
|
+
|
124
|
+
|*_E_* ~it~Get(*_IteratorType_* * +it+)
|
125
|
+
|
|
126
|
+
Alias for ~it~GetElement().
|
127
|
+
|===
|
128
|
+
|
129
|
+
=end
|
130
|
+
class HashMap < Collection
|
131
|
+
|
132
|
+
attr_reader :key
|
133
|
+
|
134
|
+
alias :value :element
|
135
|
+
|
136
|
+
def entities; super + [key] end
|
137
|
+
|
138
|
+
def initialize(type, key_type, value_type, visibility = :public)
|
139
|
+
super(type, value_type, visibility)
|
140
|
+
@key = Collection.coerce(key_type)
|
141
|
+
@entry = UserDefinedType.new(:type => entry, :identify => entryIdentify, :equal => entryEqual, :copy => entryCopy, :dtor => entryDtor)
|
142
|
+
@set = HashSet.new(set, @entry, :static)
|
143
|
+
end
|
144
|
+
|
145
|
+
def write_exported_types(stream)
|
146
|
+
stream << %$
|
147
|
+
/***
|
148
|
+
**** #{type}<#{key.type},#{value.type}> (#{self.class})
|
149
|
+
***/
|
150
|
+
$ if public?
|
151
|
+
stream << %$
|
152
|
+
typedef struct #{@entry.type} #{@entry.type};
|
153
|
+
struct #{@entry.type} {
|
154
|
+
#{key.type} key;
|
155
|
+
#{value.type} value;
|
156
|
+
unsigned flags;
|
157
|
+
};
|
158
|
+
$
|
159
|
+
@set.write_exported_types(stream)
|
160
|
+
stream << %$
|
161
|
+
typedef struct #{type} #{type};
|
162
|
+
typedef struct #{it} #{it};
|
163
|
+
struct #{type} {
|
164
|
+
#{@set.type} entries;
|
165
|
+
};
|
166
|
+
struct #{it} {
|
167
|
+
#{@set.it} it;
|
168
|
+
};
|
169
|
+
$
|
170
|
+
end
|
171
|
+
|
172
|
+
def write_exported_declarations(stream, declare, define)
|
173
|
+
stream << %$
|
174
|
+
#{declare} void #{ctor}(#{type}*);
|
175
|
+
#{declare} void #{dtor}(#{type}*);
|
176
|
+
#{declare} void #{copy}(#{type}*, #{type}*);
|
177
|
+
#{declare} int #{equal}(#{type}*, #{type}*);
|
178
|
+
#{declare} size_t #{identify}(#{type}*);
|
179
|
+
#{declare} void #{purge}(#{type}*);
|
180
|
+
#{declare} size_t #{size}(#{type}*);
|
181
|
+
#define #{empty}(self) (#{size}(self) == 0)
|
182
|
+
#{declare} int #{containsKey}(#{type}*, #{key.type});
|
183
|
+
#{declare} #{value.type} #{get}(#{type}*, #{key.type});
|
184
|
+
#{declare} int #{put}(#{type}*, #{key.type}, #{value.type});
|
185
|
+
#{declare} int #{replace}(#{type}*, #{key.type}, #{value.type});
|
186
|
+
#{declare} int #{remove}(#{type}*, #{key.type});
|
187
|
+
#{declare} void #{itCtor}(#{it}*, #{type}*);
|
188
|
+
#{declare} int #{itMove}(#{it}*);
|
189
|
+
#{declare} #{key.type} #{itGetKey}(#{it}*);
|
190
|
+
#{declare} #{value.type} #{itGetElement}(#{it}*);
|
191
|
+
#define #{itGet}(it) #{itGetElement}(it)
|
192
|
+
$
|
193
|
+
end
|
194
|
+
|
195
|
+
def write_implementations(stream, define)
|
196
|
+
stream << %$
|
197
|
+
#define AUTOC_VALID_VALUE 1
|
198
|
+
#define AUTOC_VALID_KEY 2
|
199
|
+
#define AUTOC_OWNED_VALUE 4
|
200
|
+
#define AUTOC_OWNED_KEY 8
|
201
|
+
static #{@entry.type} #{entryKeyOnlyRef}(#{key.type}* key) {
|
202
|
+
#{@entry.type} entry;
|
203
|
+
entry.key = *key;
|
204
|
+
entry.flags = AUTOC_VALID_KEY;
|
205
|
+
return entry;
|
206
|
+
}
|
207
|
+
static #{@entry.type} #{entryKeyValueRef}(#{key.type}* key, #{value.type}* value) {
|
208
|
+
#{@entry.type} entry;
|
209
|
+
entry.key = *key;
|
210
|
+
entry.value = *value;
|
211
|
+
entry.flags = (AUTOC_VALID_KEY | AUTOC_VALID_VALUE);
|
212
|
+
return entry;
|
213
|
+
}
|
214
|
+
#define #{entryIdentify}(obj) #{entryIdentifyRef}(&obj)
|
215
|
+
static size_t #{entryIdentifyRef}(#{@entry.type}* entry) {
|
216
|
+
return #{key.identify("entry->key")};
|
217
|
+
}
|
218
|
+
#define #{entryEqual}(lt, rt) #{entryEqualRef}(<, &rt)
|
219
|
+
static int #{entryEqualRef}(#{@entry.type}* lt, #{@entry.type}* rt) {
|
220
|
+
return #{key.equal("lt->key", "rt->key")};
|
221
|
+
}
|
222
|
+
#define #{entryCopy}(dst, src) #{entryCopyRef}(&dst, &src)
|
223
|
+
static void #{entryCopyRef}(#{@entry.type}* dst, #{@entry.type}* src) {
|
224
|
+
#{assert}(src->flags & AUTOC_VALID_KEY);
|
225
|
+
dst->flags = (AUTOC_VALID_KEY | AUTOC_OWNED_KEY);
|
226
|
+
#{key.copy("dst->key", "src->key")};
|
227
|
+
if(src->flags & AUTOC_VALID_VALUE) {
|
228
|
+
dst->flags |= (AUTOC_VALID_VALUE | AUTOC_OWNED_VALUE);
|
229
|
+
#{value.copy("dst->value", "src->value")};
|
230
|
+
}
|
231
|
+
}
|
232
|
+
#define #{entryDtor}(obj) #{entryDtorRef}(&obj)
|
233
|
+
static void #{entryDtorRef}(#{@entry.type}* entry) {
|
234
|
+
#{assert}(entry->flags & AUTOC_VALID_KEY);
|
235
|
+
if(entry->flags & AUTOC_OWNED_KEY) #{key.dtor("entry->key")};
|
236
|
+
if(entry->flags & AUTOC_VALID_VALUE && entry->flags & AUTOC_OWNED_VALUE) #{value.dtor("entry->value")};
|
237
|
+
}
|
238
|
+
$
|
239
|
+
@set.write_exported_declarations(stream, static, inline)
|
240
|
+
@set.write_implementations(stream, static)
|
241
|
+
stream << %$
|
242
|
+
static #{@entry.type}* #{itGetEntryRef}(#{it}*);
|
243
|
+
#{define} void #{ctor}(#{type}* self) {
|
244
|
+
#{assert}(self);
|
245
|
+
#{@set.ctor}(&self->entries);
|
246
|
+
}
|
247
|
+
#{define} void #{dtor}(#{type}* self) {
|
248
|
+
#{assert}(self);
|
249
|
+
#{@set.dtor}(&self->entries);
|
250
|
+
}
|
251
|
+
static int #{putEntryRef}(#{type}* self, #{@entry.type}* entry) {
|
252
|
+
int absent;
|
253
|
+
#{assert}(self);
|
254
|
+
#{assert}(entry);
|
255
|
+
if((absent = !#{containsKey}(self, entry->key))) {
|
256
|
+
#{@set.put}(&self->entries, *entry);
|
257
|
+
}
|
258
|
+
return absent;
|
259
|
+
}
|
260
|
+
#{define} void #{copy}(#{type}* dst, #{type}* src) {
|
261
|
+
#{it} it;
|
262
|
+
#{assert}(src);
|
263
|
+
#{assert}(dst);
|
264
|
+
#{ctor}(dst);
|
265
|
+
#{itCtor}(&it, src);
|
266
|
+
while(#{itMove}(&it)) {
|
267
|
+
#{@entry.type}* e = #{itGetEntryRef}(&it);
|
268
|
+
#{putEntryRef}(dst, e);
|
269
|
+
}
|
270
|
+
}
|
271
|
+
static int #{containsAllOf}(#{type}* self, #{type}* other) {
|
272
|
+
#{it} it;
|
273
|
+
#{itCtor}(&it, self);
|
274
|
+
while(#{itMove}(&it)) {
|
275
|
+
int found = 0;
|
276
|
+
#{@entry.type}* e = #{itGetEntryRef}(&it);
|
277
|
+
if(#{containsKey}(other, e->key)) {
|
278
|
+
#{value.type} other_value = #{get}(other, e->key);
|
279
|
+
found = #{value.equal("e->value", "other_value")};
|
280
|
+
#{value.dtor("other_value")};
|
281
|
+
}
|
282
|
+
if(!found) return 0;
|
283
|
+
}
|
284
|
+
return 1;
|
285
|
+
}
|
286
|
+
#{define} int #{equal}(#{type}* lt, #{type}* rt) {
|
287
|
+
#{assert}(lt);
|
288
|
+
#{assert}(rt);
|
289
|
+
return #{size}(lt) == #{size}(rt) && #{containsAllOf}(lt, rt) && #{containsAllOf}(rt, lt);
|
290
|
+
}
|
291
|
+
#{define} size_t #{identify}(#{type}* self) {
|
292
|
+
#{assert}(self);
|
293
|
+
return #{@set.identify}(&self->entries); /* TODO : make use of the values' hashes */
|
294
|
+
}
|
295
|
+
#{define} void #{purge}(#{type}* self) {
|
296
|
+
#{assert}(self);
|
297
|
+
#{@set.purge}(&self->entries);
|
298
|
+
}
|
299
|
+
#{define} size_t #{size}(#{type}* self) {
|
300
|
+
#{assert}(self);
|
301
|
+
return #{@set.size}(&self->entries);
|
302
|
+
}
|
303
|
+
#{define} int #{containsKey}(#{type}* self, #{key.type} key) {
|
304
|
+
int result;
|
305
|
+
#{@entry.type} entry;
|
306
|
+
#{assert}(self);
|
307
|
+
result = #{@set.contains}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
|
308
|
+
#{@entry.dtor("entry")};
|
309
|
+
return result;
|
310
|
+
}
|
311
|
+
#{define} #{value.type} #{get}(#{type}* self, #{key.type} key) {
|
312
|
+
#{value.type} result;
|
313
|
+
#{@entry.type} entry, existing_entry;
|
314
|
+
#{assert}(self);
|
315
|
+
#{assert}(#{containsKey}(self, key));
|
316
|
+
existing_entry = #{@set.get}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
|
317
|
+
#{value.copy("result", "existing_entry.value")};
|
318
|
+
#{@entry.dtor("existing_entry")};
|
319
|
+
#{@entry.dtor("entry")};
|
320
|
+
return result;
|
321
|
+
}
|
322
|
+
#{define} int #{put}(#{type}* self, #{key.type} key, #{value.type} value) {
|
323
|
+
int result;
|
324
|
+
#{@entry.type} entry;
|
325
|
+
#{assert}(self);
|
326
|
+
entry = #{entryKeyValueRef}(&key, &value);
|
327
|
+
result = #{putEntryRef}(self, &entry);
|
328
|
+
#{@entry.dtor("entry")};
|
329
|
+
return result;
|
330
|
+
}
|
331
|
+
#{define} int #{replace}(#{type}* self, #{key.type} key, #{value.type} value) {
|
332
|
+
int result;
|
333
|
+
#{@entry.type} entry;
|
334
|
+
#{assert}(self);
|
335
|
+
entry = #{entryKeyValueRef}(&key, &value);
|
336
|
+
result = #{@set.replace}(&self->entries, entry);
|
337
|
+
#{@entry.dtor("entry")};
|
338
|
+
return result;
|
339
|
+
}
|
340
|
+
#{define} int #{remove}(#{type}* self, #{key.type} key) {
|
341
|
+
int result;
|
342
|
+
#{@entry.type} entry;
|
343
|
+
#{assert}(self);
|
344
|
+
result = #{@set.remove}(&self->entries, entry = #{entryKeyOnlyRef}(&key));
|
345
|
+
#{@entry.dtor("entry")};
|
346
|
+
return result;
|
347
|
+
}
|
348
|
+
#{define} void #{itCtor}(#{it}* self, #{type}* map) {
|
349
|
+
#{assert}(self);
|
350
|
+
#{assert}(map);
|
351
|
+
#{@set.itCtor}(&self->it, &map->entries);
|
352
|
+
}
|
353
|
+
#{define} int #{itMove}(#{it}* self) {
|
354
|
+
#{assert}(self);
|
355
|
+
return #{@set.itMove}(&self->it);
|
356
|
+
}
|
357
|
+
#{define} #{key.type} #{itGetKey}(#{it}* self) {
|
358
|
+
#{@entry.type}* e;
|
359
|
+
#{key.type} key;
|
360
|
+
#{assert}(self);
|
361
|
+
e = #{itGetEntryRef}(self);
|
362
|
+
#{key.copy("key", "e->key")};
|
363
|
+
return key;
|
364
|
+
}
|
365
|
+
#{define} #{value.type} #{itGetElement}(#{it}* self) {
|
366
|
+
#{@entry.type}* e;
|
367
|
+
#{value.type} value;
|
368
|
+
#{assert}(self);
|
369
|
+
e = #{itGetEntryRef}(self);
|
370
|
+
#{assert}(e->flags & AUTOC_VALID_VALUE);
|
371
|
+
#{value.copy("value", "e->value")};
|
372
|
+
return value;
|
373
|
+
}
|
374
|
+
static #{@entry.type}* #{itGetEntryRef}(#{it}* self) {
|
375
|
+
#{assert}(self);
|
376
|
+
return #{@set.itGetRef}(&self->it);
|
377
|
+
}
|
378
|
+
#undef AUTOC_VALID_VALUE
|
379
|
+
#undef AUTOC_VALID_KEY
|
380
|
+
#undef AUTOC_OWNED_VALUE
|
381
|
+
#undef AUTOC_OWNED_KEY
|
382
|
+
$
|
383
|
+
end
|
384
|
+
|
385
|
+
end # HashMap
|
386
|
+
|
387
|
+
|
388
|
+
end # AutoC
|