set CHANGE add duplicator callback to the functions duplicating data items
diff --git a/src/set.c b/src/set.c
index b245f40..7cfda31 100644
--- a/src/set.c
+++ b/src/set.c
@@ -81,9 +81,10 @@
 }
 
 API struct ly_set *
-ly_set_dup(const struct ly_set *set)
+ly_set_dup(const struct ly_set *set, void *(*duplicator)(void *obj))
 {
     struct ly_set *new;
+    unsigned int u;
 
     LY_CHECK_ARG_RET(NULL, set, NULL);
 
@@ -93,7 +94,13 @@
     new->size = set->size;
     new->objs = malloc(new->size * sizeof *(new->objs));
     LY_CHECK_ERR_RET(!new->objs, LOGMEM(NULL); free(new), NULL);
-    memcpy(new->objs, set->objs, new->size * sizeof *(new->objs));
+    if (duplicator) {
+        for (u = 0; u < set->count; ++u) {
+            new->objs[u] = duplicator(set->objs[u]);
+        }
+    } else {
+        memcpy(new->objs, set->objs, new->size * sizeof *(new->objs));
+    }
 
     return new;
 }
@@ -129,41 +136,28 @@
 }
 
 API int
-ly_set_merge(struct ly_set *trg, struct ly_set *src, int options)
+ly_set_merge(struct ly_set *trg, struct ly_set *src, int options, void *(*duplicator)(void *obj))
 {
-    unsigned int i, ret;
-    void **new;
+    unsigned int u, c, ret = 0;
+    int i;
+    void *obj;
 
     LY_CHECK_ARG_RET(NULL, trg, -1);
     LY_CHECK_ARG_RET(NULL, src, 0);
 
-    if (!(options & LY_SET_OPT_USEASLIST)) {
-        /* remove duplicates */
-        i = 0;
-        while (i < src->count) {
-            if (ly_set_contains(trg, src->objs[i]) > -1) {
-                ly_set_rm_index(src, i);
-            } else {
-                ++i;
-            }
+    for (u = 0; u < src->count; ++u) {
+        if (duplicator) {
+            obj = duplicator(src->objs[u]);
+        } else {
+            obj = src->objs[u];
+        }
+        c = trg->count;
+        i = ly_set_add(trg, obj, options);
+        if (i > 0 && (unsigned int)i == c) {
+            ++ret;
         }
     }
 
-    /* allocate more memory if needed */
-    if (trg->size < trg->count + src->count) {
-        new = realloc(trg->objs, (trg->count + src->count) * sizeof *(trg->objs));
-        LY_CHECK_ERR_RET(!new, LOGMEM(NULL), -1);
-        trg->size = trg->count + src->count;
-        trg->objs = new;
-    }
-
-    /* copy contents from src into trg */
-    memcpy(trg->objs + trg->count, src->objs, src->count * sizeof *(src->objs));
-    ret = src->count;
-    trg->count += ret;
-
-    /* cleanup */
-    ly_set_free(src, NULL);
     return ret;
 }