* @brief Deep-copy an existing priority queue. * * The new queue gets the same item size, comparator, and elements. * Because @p src is already a valid heap under its comparator, * preserving the underlying storage layout preserves the heap * property — no re-heapify is needed. * * @param src Source queue to clone (must be non-NULL with a valid * vector and comparator). * * @r
| 247 | * failure). |
| 248 | */ |
| 249 | PriorityQueue* priority_queue_copy(const PriorityQueue* src) { |
| 250 | PQUEUE_LOG("[priority_queue_copy]: enter src=%p", (const void*)src); |
| 251 | |
| 252 | if (!src || !src->vec || !src->compare) { |
| 253 | PQUEUE_LOG("[priority_queue_copy]: NULL src / vec / compare -> NULL"); |
| 254 | return NULL; |
| 255 | } |
| 256 | |
| 257 | PriorityQueue* dst = priority_queue_create(src->vec->itemSize, src->compare); |
| 258 | if (!dst) { |
| 259 | PQUEUE_LOG("[priority_queue_copy]: priority_queue_create(itemSize=%zu) failed -> NULL", src->vec->itemSize); |
| 260 | return NULL; |
| 261 | } |
| 262 | |
| 263 | size_t n = vector_size(src->vec); |
| 264 | if (n > 0 && !vector_reserve(dst->vec, n)) { |
| 265 | PQUEUE_LOG("[priority_queue_copy]: vector_reserve(%zu) failed -> NULL", n); |
| 266 | priority_queue_deallocate(dst); |
| 267 | |
| 268 | return NULL; |
| 269 | } |
| 270 | for (size_t i = 0; i < n; ++i) { |
| 271 | void* elem = vector_at(src->vec, i); |
| 272 | if (!elem || !vector_push_back(dst->vec, elem)) { |
| 273 | PQUEUE_LOG("[priority_queue_copy]: push_back failed at index %zu -> NULL", i); |
| 274 | priority_queue_deallocate(dst); |
| 275 | |
| 276 | return NULL; |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | PQUEUE_LOG("[priority_queue_copy]: exit ok dst=%p (%zu elements copied)", (void*)dst, n); |
| 281 | return dst; |
| 282 | } |
| 283 | |
| 284 | |
| 285 | /** |
nothing calls this directly
no test coverage detected