+// ------------------------------- type_t -------------------------------
+
+char ptr_equals(const void*o1, const void*o2)
+{
+ return o1==o2;
+}
+unsigned int ptr_hash(const void*o)
+{
+ return string_hash3(o, sizeof(o));
+}
+void* ptr_dup(const void*o)
+{
+ return (void*)o;
+}
+void ptr_free(void*o)
+{
+ return;
+}
+
+char charptr_equals(const void*o1, const void*o2)
+{
+ if(!o1 || !o2)
+ return o1==o2;
+ return !strcmp(o1,o2);
+}
+unsigned int charptr_hash(const void*o)
+{
+ if(!o)
+ return 0;
+ return string_hash2(o);
+}
+void* charptr_dup(const void*o)
+{
+ if(!o)
+ return 0;
+ return strdup(o);
+}
+void charptr_free(void*o)
+{
+ if(o) {
+ rfx_free(o);
+ }
+}
+
+char stringstruct_equals(const void*o1, const void*o2)
+{
+ if(!o1 || !o2)
+ return o1==o2;
+ string_t*s1 = (string_t*)o1;
+ string_t*s2 = (string_t*)o2;
+ int l = s1->len<s2->len?s1->len:s2->len;
+ int r = memcmp(s1->str, s2->str, l);
+ if(r)
+ return 0;
+ else
+ return s1->len==s2->len;
+}
+unsigned int stringstruct_hash(const void*o)
+{
+ if(!o) return 0;
+ return string_hash(o);
+}
+string_t*string_dup3(string_t*o)
+{
+ if(!o) return 0;
+ if(!o->str) {
+ string_t*s = malloc(sizeof(string_t));
+ s->str=0;
+ s->len=0;
+ return s;
+ }
+ string_t*s = rfx_alloc(sizeof(string_t)+o->len+1);
+ s->len = o->len;
+ s->str = (const char*)(s+1);
+ memcpy((char*)s->str, o->str, s->len);
+ ((char*)s->str)[s->len]=0;
+ return s;
+}
+void stringstruct_free(void*o)
+{
+ if(o)
+ string_free(o);
+}
+
+type_t ptr_type = {
+ equals: ptr_equals,
+ hash: ptr_hash,
+ dup: ptr_dup,
+ free: ptr_free,
+};
+
+type_t charptr_type = {
+ equals: charptr_equals,
+ hash: charptr_hash,
+ dup: charptr_dup,
+ free: charptr_free,
+};
+
+type_t stringstruct_type = {
+ equals: stringstruct_equals,
+ hash: stringstruct_hash,
+ dup: (dup_func)string_dup3,
+ free: stringstruct_free,
+};