lib/autoc/collection/hash_set.rb in autoc-1.1 vs lib/autoc/collection/hash_set.rb in autoc-1.2
- old
+ new
@@ -146,68 +146,71 @@
class HashSet < Collection
def initialize(*args)
super
@list = List.new(list, element, :static)
+ @capability.subtract [:orderable]
+ key_type_check(element)
end
- def write_exported_types(stream)
+ def write_intf_types(stream)
stream << %$
/***
**** #{type}<#{element.type}> (#{self.class})
***/
$ if public?
- @list.write_exported_types(stream)
+ @list.write_intf_types(stream)
stream << %$
typedef struct #{type} #{type};
typedef struct #{it} #{it};
struct #{type} {
- #{@list.type}* buckets;
+ #{@list.type_ref} buckets;
size_t bucket_count, min_bucket_count;
size_t size, min_size, max_size;
unsigned min_fill, max_fill, capacity_multiplier; /* ?*1e-2 */
};
struct #{it} {
- #{type}* set;
+ #{type_ref} set;
int bucket_index;
#{@list.it} it;
};
$
end
- def write_exported_declarations(stream, declare, define)
+ def write_intf_decls(stream, declare, define)
+ super
stream << %$
- #{declare} void #{ctor}(#{type}*);
- #{declare} void #{dtor}(#{type}*);
- #{declare} void #{copy}(#{type}*, #{type}*);
- #{declare} int #{equal}(#{type}*, #{type}*);
- #{declare} size_t #{identify}(#{type}*);
- #{declare} void #{purge}(#{type}*);
- #{declare} int #{contains}(#{type}*, #{element.type});
- #{declare} #{element.type} #{get}(#{type}*, #{element.type});
- #{declare} size_t #{size}(#{type}*);
+ #{declare} #{ctor.declaration};
+ #{declare} #{dtor.declaration};
+ #{declare} #{copy.declaration};
+ #{declare} #{equal.declaration};
+ #{declare} #{identify.declaration};
+ #{declare} void #{purge}(#{type_ref});
+ #{declare} int #{contains}(#{type_ref}, #{element.type});
+ #{declare} #{element.type} #{get}(#{type_ref}, #{element.type});
+ #{declare} size_t #{size}(#{type_ref});
#define #{empty}(self) (#{size}(self) == 0)
- #{declare} int #{put}(#{type}*, #{element.type});
- #{declare} int #{replace}(#{type}*, #{element.type});
- #{declare} int #{remove}(#{type}*, #{element.type});
- #{declare} void #{exclude}(#{type}*, #{type}*);
- #{declare} void #{retain}(#{type}*, #{type}*);
- #{declare} void #{include}(#{type}*, #{type}*);
- #{declare} void #{invert}(#{type}*, #{type}*);
- #{declare} void #{itCtor}(#{it}*, #{type}*);
- #{declare} int #{itMove}(#{it}*);
- #{declare} #{element.type} #{itGet}(#{it}*);
+ #{declare} int #{put}(#{type_ref}, #{element.type});
+ #{declare} int #{replace}(#{type_ref}, #{element.type});
+ #{declare} int #{remove}(#{type_ref}, #{element.type});
+ #{declare} void #{exclude}(#{type_ref}, #{type_ref});
+ #{declare} void #{retain}(#{type_ref}, #{type_ref});
+ #{declare} void #{include}(#{type_ref}, #{type_ref});
+ #{declare} void #{invert}(#{type_ref}, #{type_ref});
+ #{declare} void #{itCtor}(#{it_ref}, #{type_ref});
+ #{declare} int #{itMove}(#{it_ref});
+ #{declare} #{element.type} #{itGet}(#{it_ref});
$
end
- def write_implementations(stream, define)
- @list.write_exported_declarations(stream, static, inline)
- @list.write_implementations(stream, static)
+ def write_impls(stream, define)
+ @list.write_intf_decls(stream, static, inline)
+ @list.write_impls(stream, static)
stream << %$
- #{define} #{element.type}* #{itGetRef}(#{it}*);
- static void #{rehash}(#{type}* self) {
- #{@list.type}* buckets;
+ #{define} #{element.type_ref} #{itGetRef}(#{it_ref});
+ static void #{rehash}(#{type_ref} self) {
+ #{@list.type_ref} buckets;
size_t index, bucket_count, size, fill;
#{assert}(self);
#{assert}(self->min_fill > 0);
#{assert}(self->max_fill > 0);
#{assert}(self->min_fill < self->max_fill);
@@ -228,11 +231,11 @@
self->max_size = (size_t)((float)self->max_fill/100*size);
} else {
bucket_count = self->min_bucket_count;
size = 0;
}
- buckets = (#{@list.type}*)#{malloc}(bucket_count*sizeof(#{@list.type})); #{assert}(buckets);
+ buckets = (#{@list.type_ref})#{malloc}(bucket_count*sizeof(#{@list.type})); #{assert}(buckets);
for(index = 0; index < bucket_count; ++index) {
#{@list.ctor}(&buckets[index]);
}
if(self->buckets) {
#{it} it;
@@ -248,53 +251,53 @@
}
self->buckets = buckets;
self->bucket_count = bucket_count;
self->size = size;
}
- #{define} void #{ctor}(#{type}* self) {
+ static int #{containsAllOf}(#{type_ref} self, #{type_ref} other) {
+ #{it} it;
+ #{itCtor}(&it, self);
+ while(#{itMove}(&it)) {
+ int found = 0;
+ if(#{contains}(other, *#{itGetRef}(&it))) found = 1;
+ if(!found) return 0;
+ }
+ return 1;
+ }
+ #{define} #{ctor.definition} {
#{assert}(self);
self->min_bucket_count = 16;
self->min_fill = 20;
self->max_fill = 80;
self->min_size = (size_t)((float)self->min_fill/100*self->min_bucket_count);
self->max_size = (size_t)((float)self->max_fill/100*self->min_bucket_count);
self->capacity_multiplier = 200;
self->buckets = NULL;
#{rehash}(self);
}
- #{define} void #{dtor}(#{type}* self) {
+ #{define} #{dtor.definition} {
size_t i;
#{assert}(self);
for(i = 0; i < self->bucket_count; ++i) {
#{@list.dtor}(&self->buckets[i]);
}
#{free}(self->buckets);
}
- #{define} void #{copy}(#{type}* dst, #{type}* src) {
+ #{define} #{copy.definition} {
#{it} it;
#{assert}(src);
#{assert}(dst);
#{ctor}(dst);
#{itCtor}(&it, src);
while(#{itMove}(&it)) #{put}(dst, *#{itGetRef}(&it));
}
- static int #{containsAllOf}(#{type}* self, #{type}* other) {
- #{it} it;
- #{itCtor}(&it, self);
- while(#{itMove}(&it)) {
- int found = 0;
- if(#{contains}(other, *#{itGetRef}(&it))) found = 1;
- if(!found) return 0;
- }
- return 1;
- }
- #{define} int #{equal}(#{type}* lt, #{type}* rt) {
+ #{define} #{equal.definition} {
#{assert}(lt);
#{assert}(rt);
return #{size}(lt) == #{size}(rt) && #{containsAllOf}(lt, rt) && #{containsAllOf}(rt, lt);
}
- #{define} size_t #{identify}(#{type}* self) {
+ #{define} #{identify.definition} {
#{it} it;
size_t result = 0;
#{assert}(self);
#{itCtor}(&it, self);
while(#{itMove}(&it)) {
@@ -302,75 +305,75 @@
result ^= #{element.identify("*e")};
result = AUTOC_RCYCLE(result);
}
return result;
}
- #{define} void #{purge}(#{type}* self) {
+ #{define} void #{purge}(#{type_ref} self) {
#{assert}(self);
#{dtor}(self);
self->buckets = NULL;
#{rehash}(self);
}
- #{define} int #{contains}(#{type}* self, #{element.type} element) {
+ #{define} int #{contains}(#{type_ref} self, #{element.type} element) {
#{assert}(self);
return #{@list.contains}(&self->buckets[#{element.identify("element")} % self->bucket_count], element);
}
- #{define} #{element.type} #{get}(#{type}* self, #{element.type} element) {
+ #{define} #{element.type} #{get}(#{type_ref} self, #{element.type} element) {
#{element.type} result;
#{assert}(self);
#{assert}(#{contains}(self, element));
result = #{@list.find}(&self->buckets[#{element.identify("element")} % self->bucket_count], element);
return result;
}
- #{define} size_t #{size}(#{type}* self) {
+ #{define} size_t #{size}(#{type_ref} self) {
#{assert}(self);
return self->size;
}
- #{define} int #{put}(#{type}* self, #{element.type} element) {
- #{@list.type}* bucket;
+ #{define} int #{put}(#{type_ref} self, #{element.type} element) {
+ #{@list.type_ref} bucket;
#{assert}(self);
bucket = &self->buckets[#{element.identify("element")} % self->bucket_count];
if(!#{@list.contains}(bucket, element)) {
#{@list.push}(bucket, element);
++self->size;
#{rehash}(self);
return 1;
}
return 0;
}
- #{define} int #{replace}(#{type}* self, #{element.type} element) {
- #{@list.type}* bucket;
+ #{define} int #{replace}(#{type_ref} self, #{element.type} element) {
+ #{@list.type_ref} bucket;
#{assert}(self);
bucket = &self->buckets[#{element.identify("element")} % self->bucket_count];
return #{@list.replace}(bucket, element);
}
- #{define} int #{remove}(#{type}* self, #{element.type} element) {
- #{@list.type}* bucket;
+ #{define} int #{remove}(#{type_ref} self, #{element.type} element) {
+ #{@list.type_ref} bucket;
#{assert}(self);
bucket = &self->buckets[#{element.identify("element")} % self->bucket_count];
if(#{@list.remove}(bucket, element)) {
--self->size;
#{rehash}(self);
return 1;
}
return 0;
}
- #{define} void #{exclude}(#{type}* self, #{type}* other) {
+ #{define} void #{exclude}(#{type_ref} self, #{type_ref} other) {
#{it} it;
#{assert}(self);
#{assert}(other);
#{itCtor}(&it, other);
while(#{itMove}(&it)) #{remove}(self, *#{itGetRef}(&it));
}
- #{define} void #{include}(#{type}* self, #{type}* other) {
+ #{define} void #{include}(#{type_ref} self, #{type_ref} other) {
#{it} it;
#{assert}(self);
#{assert}(other);
#{itCtor}(&it, other);
while(#{itMove}(&it)) #{put}(self, *#{itGetRef}(&it));
}
- #{define} void #{retain}(#{type}* self, #{type}* other) {
+ #{define} void #{retain}(#{type_ref} self, #{type_ref} other) {
#{it} it;
#{type} set;
#{assert}(self);
#{assert}(other);
#{ctor}(&set);
@@ -380,11 +383,11 @@
if(#{contains}(other, *e)) #{put}(&set, *e);
}
#{dtor}(self);
*self = set;
}
- #{define} void #{invert}(#{type}* self, #{type}* other) {
+ #{define} void #{invert}(#{type_ref} self, #{type_ref} other) {
#{it} it;
#{type} set;
#{assert}(self);
#{assert}(other);
#{ctor}(&set);
@@ -399,35 +402,42 @@
if(!#{contains}(self, *e)) #{put}(&set, *e);
}
#{dtor}(self);
*self = set;
}
- #{define} void #{itCtor}(#{it}* self, #{type}* set) {
+ #{define} void #{itCtor}(#{it_ref} self, #{type_ref} set) {
#{assert}(self);
self->set = set;
self->bucket_index = -1;
}
- #{define} int #{itMove}(#{it}* self) {
+ #{define} int #{itMove}(#{it_ref} self) {
#{assert}(self);
if(self->bucket_index < 0) #{@list.itCtor}(&self->it, &self->set->buckets[self->bucket_index = 0]);
if(#{@list.itMove}(&self->it)) return 1;
while(++self->bucket_index < self->set->bucket_count) {
#{@list.itCtor}(&self->it, &self->set->buckets[self->bucket_index]);
if(#{@list.itMove}(&self->it)) return 1;
}
return 0;
}
- #{define} #{element.type} #{itGet}(#{it}* self) {
+ #{define} #{element.type} #{itGet}(#{it_ref} self) {
#{assert}(self);
return #{@list.itGet}(&self->it);
}
- #{define} #{element.type}* #{itGetRef}(#{it}* self) {
+ #{define} #{element.type_ref} #{itGetRef}(#{it_ref} self) {
#{assert}(self);
return #{@list.itGetRef}(&self->it);
}
$
end
+ private
+
+ def key_type_check(obj)
+ raise "type #{obj.type} (#{obj}) must be hashable" unless obj.hashable?
+ element_type_check(obj)
+ end
+
end # HashSet
end # AutoC
\ No newline at end of file