diff --git a/src/container/priqueue.c b/src/container/priqueue.c index d4b4c1c4a..b06c70d77 100644 --- a/src/container/priqueue.c +++ b/src/container/priqueue.c @@ -33,6 +33,7 @@ PriQueue priqueue_init (PriQueue self, size_t element_size, priqueue_cmp_fn cmpfn, + priqueue_copy_fn copyfn, priqueue_resize_fn resizefn) { NOBUG_INIT_FLAG (priqueue); @@ -48,6 +49,10 @@ priqueue_init (PriQueue self, self->used = self->high_water = self->low_water = 0; self->cmpfn = cmpfn; + if (!copyfn) + copyfn = memcpy; + self->copyfn = copyfn; + if (!resizefn) resizefn = priqueue_clib_resize; self->resizefn = resizefn; @@ -177,11 +182,11 @@ pq_up (PriQueue self, void* tmp) while (p && self->cmpfn (tmp, pq_index(self, p-1)) < 0) { - memcpy (pq_index (self, i-1), pq_index (self, p-1), self->element_size); + self->copyfn (pq_index (self, i-1), pq_index (self, p-1), self->element_size); i=p; p=i/2; } - memcpy (pq_index (self, i-1), tmp, self->element_size); + self->copyfn (pq_index (self, i-1), tmp, self->element_size); } @@ -222,10 +227,10 @@ pq_down (PriQueue self, void* tmp) if (self->cmpfn (tmp, pq_index(self, n-1)) < 0) break; - memcpy (pq_index (self, i-1), pq_index (self, n-1), self->element_size); + self->copyfn (pq_index (self, i-1), pq_index (self, n-1), self->element_size); i = n; } - memcpy (pq_index (self, i-1), tmp, self->element_size); + self->copyfn (pq_index (self, i-1), tmp, self->element_size); } @@ -257,7 +262,7 @@ priqueue_remove (PriQueue self) -#if 0 /* testing */ +#ifdef PRIQUEUE_TEST /* testing */ #include @@ -303,10 +308,11 @@ int main() r = priqueue_init (&pq, sizeof (int), cmpintptr, + NULL, NULL); ENSURE (r==&pq); -#if 0 +#if 1 data = 10; r = priqueue_insert (&pq, &data); ENSURE (r==&pq); diff --git a/src/container/priqueue.h b/src/container/priqueue.h index 16c0e7ce3..b74062d80 100644 --- a/src/container/priqueue.h +++ b/src/container/priqueue.h @@ -42,6 +42,9 @@ typedef priqueue* PriQueue; /* function to compare 2 keys, mandatory */ typedef int (*priqueue_cmp_fn)(void*, void*); +/* function to copy elements, optional. Has the same prototype as memcpy which is used by default */ +typedef void *(*priqueue_copy_fn)(void *dest, const void *src, size_t n); + /* called when used hits the high or low water marks and initially by priqueue_init() (with queue==NULL) or at priqueue_destroy (with queue != NULL, used elements == 0), optional. @@ -64,6 +67,7 @@ struct priqueue_struct unsigned low_water; // size for shrinking the queue priqueue_cmp_fn cmpfn; + priqueue_copy_fn copyfn; priqueue_resize_fn resizefn; }; @@ -77,6 +81,7 @@ PriQueue priqueue_init (PriQueue self, size_t element_size, priqueue_cmp_fn cmpfn, + priqueue_copy_fn copyfn, priqueue_resize_fn resizefn);