From 918b73ad51213928d3ee411a56ba935ef17948b2 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 15 May 2019 15:22:59 -0300 Subject: [PATCH] Fifth update on iterators - HEAP --- examples/heap/iterator.c | 181 ++++++++++++++++++++++++++++++ examples/iterators/heap.c | 31 +++--- src/deque.h | 1 + src/hashmap.h | 7 ++ src/hashset.h | 7 ++ src/heap.h | 229 ++++++++++++++++++++++++-------------- 6 files changed, 360 insertions(+), 96 deletions(-) create mode 100644 examples/heap/iterator.c diff --git a/examples/heap/iterator.c b/examples/heap/iterator.c new file mode 100644 index 0000000..79a4fe5 --- /dev/null +++ b/examples/heap/iterator.c @@ -0,0 +1,181 @@ +/** + * iterator.c + * + * Creation Date: 15/05/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + * Iterator Example + */ +#include "heap.h" +#include +#include + +// Int compare function +int intcmp(int a, int b) +{ + return a - b; +} + +// Creates a heap of integers +HEAP_GENERATE(h, heap, /* FMOD */, int) + +int main(int argc, char const *argv[]) +{ + // Create a new max heap with an initial capacity of 100 + heap *my_heap = h_new(100, MaxHeap, intcmp); + + // Add elements to the heap + for (int i = 0; i < 20; i++) + { + h_insert(my_heap, i); + } + + // Iterate from the start (index 0) to the end (index count - 1) of the heap + for (heap_iter it = my_heap->it_start(my_heap); // Initialize iterator 'it' to the start of the heap + !h_iter_end(&it); // Conditional stop (until it is not at the end) + h_iter_next(&it)) // Iterator goes one position forward + { + // Access the current element + int e = h_iter_value(&it); + + // Access the current index (index is relative to all the elements in the iteration) + size_t i = h_iter_index(&it); + + // Print heap + + // Index is useful in situations like this + // If it is the first element + if (i == 0) + printf("[ %d, ", e); + // If it is the last element + else if (i == h_count(my_heap) - 1) + printf("%d ]\n", e); + // For elements at the middle + else + printf("%d, ", e); + } + + // Index can also be used to iterate over a certain portion of a collection + size_t limit = h_count(my_heap) / 2; + for (heap_iter it = my_heap->it_start(my_heap); !h_iter_end(&it); h_iter_next(&it)) + { + // Access the current element + int e = h_iter_value(&it); + + // Access the current index (index is relative to all the elements in the iteration) + size_t i = h_iter_index(&it); + + // Print heap up until limit + + // If it is the first element + if (i == 0) + printf("[ %d, ", e); + // If it is the last element + else if (i == limit - 1) // -1 because index is 0 based and we want half of the heap + { + printf("%d ]\n", e); + break; + } + // For elements at the middle + else + printf("%d, ", e); + } + + // Going backwards + for (heap_iter it = my_heap->it_end(my_heap); // Initialize iterator 'it' to the end of the heap + !h_iter_start(&it); // Conditional stop (until it is not at the start) + h_iter_prev(&it)) // Iterator goes one position backwards + { + // Access the current element + int e = h_iter_value(&it); + + // Access the current index (index is relative to all the elements in the iteration) + size_t i = h_iter_index(&it); + + // Print heap + // Note how the conditions for the first and last elements are simply swapped + // Because iterating backwards make the first element be the index count - 1 + // and the last one be the index 0 + + // If it is the first element + if (i == h_count(my_heap) - 1) + printf("[ %d, ", e); + // If it is the last element + else if (i == 0) + printf("%d ]\n", e); + // For elements at the middle + else + printf("%d, ", e); + } + + // You can also use iterators in a while loop + // But to do so you must declare the iterator struct outside the loop first + heap_iter it; + + // You have three options: + // - Initialize it using the functions provided by the heap [ my_heap->it_start() and my_heap->it_end() ] + // - Initialize it using the init() function (when the iterator is already allocated) + // - Initialize it using the new() function (allocates on the heap, pointers only) + + it = my_heap->it_start(my_heap); + it = my_heap->it_end(my_heap); + + // This is equivalent to it_start() + h_iter_init(&it, my_heap); + + // For pointers + // Also equivalent to it_start() + heap_iter *iter = h_iter_new(my_heap); + + // The actual while loop + while (!h_iter_end(iter)) + { + // Accessing elements + int e = h_iter_value(iter); + size_t i = h_iter_index(iter); + + // Print index and element + printf("heap[%2" PRIuMAX "] = %2d\n", i, e); + + // Move iterator forwards + h_iter_next(iter); + } + + // Send the iterator to the start of the heap + h_iter_to_start(iter); + + // Send the iterator to the end of the heap + h_iter_to_end(iter); + + // Backwards loop + while (!h_iter_start(iter)) + { + // Accessing elements + int e = h_iter_value(iter); + size_t i = h_iter_index(iter); + + // Print index and element + printf("heap[%2" PRIuMAX "] = %2d\n", i, e); + + // Move iterator backwards + h_iter_prev(iter); + } + + // Certain iterators also allow you to modify the contents it is iterating over + // Exceptions are collections that depend of the current state of the element + // like tree-based collections and heap (collections that have some kind of ordering). + // You also can't change the keys of an associative collection + + // In the case of a heap this is not possible because the heap have its + // elements ordered. Changing them could cause the heap to be in an invalid + // state. + + // Dispose the iterator called by h_iter_new() + h_iter_free(iter); + // Dispose the heap created + h_free(my_heap); + + return 0; +} diff --git a/examples/iterators/heap.c b/examples/iterators/heap.c index 4aa8841..8c79fe0 100644 --- a/examples/iterators/heap.c +++ b/examples/iterators/heap.c @@ -20,12 +20,9 @@ HEAP_GENERATE(h, heap, static, int) int main(int argc, char const *argv[]) { - size_t i; - int r; - // Initialize heap and add some elements - heap *h = h_new(10, MinHeap, intcmp); - for (int i = 9; i >= 0; i--) + heap *h = h_new(10, MaxHeap, intcmp); + for (int i = 0; i < 10; i++) h_insert(h, i); // Initialize iterator @@ -35,26 +32,30 @@ int main(int argc, char const *argv[]) // Make the iterator go back and forward for (int j = 0; j < 4; j++) { - while (h_iter_next(&iter, &r, &i)) - printf("C[%2d] = %2d\n", i, r); + while (!h_iter_end(&iter)) + { + printf("C[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); + h_iter_next(&iter); + } printf("\n"); - while (h_iter_prev(&iter, &r, &i)) - printf("C[%2d] = %2d\n", i, r); + while (!h_iter_start(&iter)) + { + printf("C[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); + h_iter_prev(&iter); + } printf("\n\n"); } - for (h_iter_tostart(&iter); !h_iter_end(&iter); /**/) + for (h_iter_to_start(&iter); !h_iter_end(&iter); h_iter_next(&iter)) { - h_iter_next(&iter, &r, &i); - printf("H[%2d] = %2d\n", i, r); + printf("H[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); } printf("\n"); - for (h_iter_toend(&iter); !h_iter_start(&iter); /**/) + for (h_iter_to_end(&iter); !h_iter_start(&iter); h_iter_prev(&iter)) { - h_iter_prev(&iter, &r, &i); - printf("H[%2d] = %2d\n", i, r); + printf("H[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); } h_free(h); diff --git a/src/deque.h b/src/deque.h index 996e00d..deab64b 100644 --- a/src/deque.h +++ b/src/deque.h @@ -135,6 +135,7 @@ /* SOURCE ********************************************************************/ #define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ + /* Implementation Detail Functions */ \ FMOD bool PFX##_impl_grow(SNAME *_deque_); \ SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \ SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \ diff --git a/src/hashmap.h b/src/hashmap.h index 1884936..f430f9d 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -178,6 +178,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ FMOD size_t PFX##_count(SNAME *_map_); \ + FMOD size_t PFX##_capacity(SNAME *_map_); \ \ /* Iterator Functions */ \ /* Iterator Allocation and Deallocation */ \ @@ -202,6 +203,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, /* SOURCE ********************************************************************/ #define HASHMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V) \ \ + /* Implementation Detail Functions */ \ FMOD bool PFX##_impl_grow(SNAME *_map_); \ FMOD SNAME##_entry *PFX##_impl_get_entry(SNAME *_map_, K key); \ FMOD size_t PFX##_impl_calculate_size(size_t required); \ @@ -442,6 +444,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return _map_->count; \ } \ \ + FMOD size_t PFX##_capacity(SNAME *_map_) \ + { \ + return _map_->capacity; \ + } \ + \ FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \ { \ SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \ diff --git a/src/hashset.h b/src/hashset.h index 01bbbc9..af24a23 100644 --- a/src/hashset.h +++ b/src/hashset.h @@ -172,6 +172,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD bool PFX##_contains(SNAME *_set_, V element); \ FMOD bool PFX##_empty(SNAME *_set_); \ FMOD size_t PFX##_count(SNAME *_set_); \ + FMOD size_t PFX##_capacity(SNAME *_set_); \ \ /* Set Operations */ \ FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \ @@ -200,6 +201,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, /* SOURCE ********************************************************************/ #define HASHSET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ + /* Implementation Detail Functions */ \ FMOD bool PFX##_grow(SNAME *_set_); \ FMOD SNAME##_entry *PFX##_get_entry(SNAME *_set_, V element); \ FMOD size_t PFX##_calculate_size(size_t required); \ @@ -399,6 +401,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return _set_->count; \ } \ \ + FMOD size_t PFX##_capacity(SNAME *_set_) \ + { \ + return _set_->capacity; \ + } \ + \ FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \ { \ SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \ diff --git a/src/heap.h b/src/heap.h index 717d2e2..dd055e5 100644 --- a/src/heap.h +++ b/src/heap.h @@ -43,65 +43,105 @@ typedef enum HeapOrder #define HEAP_GENERATE_SOURCE_PUBLIC(PFX, SNAME, FMOD, K, V) \ HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) /* STRUCT ********************************************************************/ -#define HEAP_GENERATE_STRUCT(PFX, SNAME, FMOD, V) \ - \ - struct SNAME##_s \ - { \ - V *buffer; \ - size_t capacity; \ - size_t count; \ - enum HeapOrder HO; \ - int (*cmp)(V, V); \ - }; \ - \ - struct SNAME##_iter_s \ - { \ - struct SNAME##_s *target; \ - size_t cursor; \ - bool start; \ - bool end; \ - }; \ - \ +#define HEAP_GENERATE_STRUCT(PFX, SNAME, FMOD, V) + /* HEADER ********************************************************************/ -#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \ - \ - typedef struct SNAME##_s SNAME; \ - typedef struct SNAME##_iter_s SNAME##_iter; \ - \ - FMOD SNAME *PFX##_new(size_t size, HeapOrder HO, int (*compare)(V, V)); \ - FMOD void PFX##_clear(SNAME *_heap_); \ - FMOD void PFX##_free(SNAME *_heap_); \ - FMOD bool PFX##_insert(SNAME *_heap_, V element); \ - FMOD bool PFX##_remove(SNAME *_heap_, V *result); \ - FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \ - FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \ - FMOD V PFX##_peek(SNAME *_heap_); \ - FMOD V *PFX##_peek_ref(SNAME *_heap_); \ - FMOD bool PFX##_contains(SNAME *_heap_, V element); \ - FMOD bool PFX##_empty(SNAME *_heap_); \ - FMOD bool PFX##_full(SNAME *_heap_); \ - FMOD size_t PFX##_count(SNAME *_heap_); \ - FMOD size_t PFX##_capacity(SNAME *_heap_); \ - \ - FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \ - FMOD void PFX##_iter_free(SNAME##_iter *iter); \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ - FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \ - FMOD void PFX##_iter_toend(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \ - \ +#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \ + \ + /* Heap Structure */ \ + typedef struct SNAME##_s \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements in the heap */ \ + size_t count; \ + \ + /* Heap order (MaxHeap or MinHeap) */ \ + enum HeapOrder HO; \ + \ + /* Element comparison function */ \ + int (*cmp)(V, V); \ + \ + /* Function that returns an iterator to the start of the heap */ \ + struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \ + \ + /* Function that returns an iterator to the end of the heap */ \ + struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \ + \ + } SNAME, *SNAME##_ptr; \ + \ + /* Heap Iterator */ \ + typedef struct SNAME##_iter_s \ + { \ + /* Target heap */ \ + struct SNAME##_s *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + \ + } SNAME##_iter, *SNAME##_iter_ptr; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + FMOD SNAME *PFX##_new(size_t size, HeapOrder HO, int (*compare)(V, V)); \ + FMOD void PFX##_clear(SNAME *_heap_); \ + FMOD void PFX##_free(SNAME *_heap_); \ + /* Collection Input and Output */ \ + FMOD bool PFX##_insert(SNAME *_heap_, V element); \ + FMOD bool PFX##_remove(SNAME *_heap_, V *result); \ + /* Conditional Input and Output */ \ + FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \ + FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \ + /* Element Access */ \ + FMOD V PFX##_peek(SNAME *_heap_); \ + FMOD V *PFX##_peek_ref(SNAME *_heap_); \ + /* Collection State */ \ + FMOD bool PFX##_contains(SNAME *_heap_, V element); \ + FMOD bool PFX##_empty(SNAME *_heap_); \ + FMOD bool PFX##_full(SNAME *_heap_); \ + FMOD size_t PFX##_count(SNAME *_heap_); \ + FMOD size_t PFX##_capacity(SNAME *_heap_); \ + \ + /* Iterator Functions */ \ + /* Iterator Allocation and Deallocation */ \ + FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \ + FMOD void PFX##_iter_free(SNAME##_iter *iter); \ + /* Iterator Initialization */ \ + FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \ + /* Iterator State */ \ + FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ + FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ + /* Iterator Movement */ \ + FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \ + FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \ + FMOD bool PFX##_iter_next(SNAME##_iter *iter); \ + FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \ + /* Iterator Access */ \ + FMOD V PFX##_iter_value(SNAME##_iter *iter); \ + FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \ + \ /* SOURCE ********************************************************************/ #define HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ - FMOD bool PFX##_grow(SNAME *_heap_); \ - FMOD size_t PFX##_p(size_t index); \ - FMOD size_t PFX##_l(size_t index); \ - FMOD size_t PFX##_r(size_t index); \ - FMOD bool PFX##_float_up(SNAME *_heap_, size_t index); \ - FMOD bool PFX##_float_down(SNAME *_heap_, size_t index); \ + /* Implementation Detail Functions */ \ + FMOD bool PFX##_impl_grow(SNAME *_heap_); \ + FMOD size_t PFX##_impl_p(size_t index); \ + FMOD size_t PFX##_impl_l(size_t index); \ + FMOD size_t PFX##_impl_r(size_t index); \ + FMOD bool PFX##_impl_float_up(SNAME *_heap_, size_t index); \ + FMOD bool PFX##_impl_float_down(SNAME *_heap_, size_t index); \ + SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ + SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ \ FMOD SNAME *PFX##_new(size_t size, HeapOrder HO, int (*compare)(V, V)) \ { \ @@ -131,6 +171,9 @@ typedef enum HeapOrder _heap_->HO = HO; \ _heap_->cmp = compare; \ \ + _heap_->it_start = PFX##_impl_it_start; \ + _heap_->it_end = PFX##_impl_it_end; \ + \ return _heap_; \ } \ \ @@ -151,7 +194,7 @@ typedef enum HeapOrder { \ if (PFX##_full(_heap_)) \ { \ - if (!PFX##_grow(_heap_)) \ + if (!PFX##_impl_grow(_heap_)) \ return false; \ } \ \ @@ -163,7 +206,7 @@ typedef enum HeapOrder \ _heap_->buffer[_heap_->count++] = element; \ \ - if (!PFX##_float_up(_heap_, _heap_->count - 1)) \ + if (!PFX##_impl_float_up(_heap_, _heap_->count - 1)) \ return false; \ \ return true; \ @@ -180,7 +223,7 @@ typedef enum HeapOrder \ _heap_->count--; \ \ - if (!PFX##_float_down(_heap_, 0)) \ + if (!PFX##_impl_float_down(_heap_, 0)) \ return false; \ \ return true; \ @@ -284,28 +327,25 @@ typedef enum HeapOrder return PFX##_empty(iter->target) || iter->end; \ } \ \ - FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \ + FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \ { \ iter->cursor = 0; \ iter->start = true; \ iter->end = PFX##_empty(iter->target); \ } \ \ - FMOD void PFX##_iter_toend(SNAME##_iter *iter) \ + FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \ { \ iter->cursor = iter->target->count - 1; \ iter->start = PFX##_empty(iter->target); \ iter->end = true; \ } \ \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index) \ + FMOD bool PFX##_iter_next(SNAME##_iter *iter) \ { \ if (iter->end) \ return false; \ \ - *index = iter->cursor; \ - *result = iter->target->buffer[iter->cursor]; \ - \ iter->start = false; \ \ if (iter->cursor == iter->target->count - 1) \ @@ -316,14 +356,11 @@ typedef enum HeapOrder return true; \ } \ \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index) \ + FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \ { \ if (iter->start) \ return false; \ \ - *index = iter->cursor; \ - *result = iter->target->buffer[iter->cursor]; \ - \ iter->end = false; \ \ if (iter->cursor == 0) \ @@ -334,7 +371,17 @@ typedef enum HeapOrder return true; \ } \ \ - FMOD bool PFX##_grow(SNAME *_heap_) \ + FMOD V PFX##_iter_value(SNAME##_iter *iter) \ + { \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \ + { \ + return iter->cursor; \ + } \ + \ + FMOD bool PFX##_impl_grow(SNAME *_heap_) \ { \ size_t new_capacity = _heap_->capacity * 2; \ \ @@ -349,7 +396,7 @@ typedef enum HeapOrder return true; \ } \ \ - FMOD size_t PFX##_p(size_t index) \ + FMOD size_t PFX##_impl_p(size_t index) \ { \ if (index == 0) \ return 0; \ @@ -357,47 +404,47 @@ typedef enum HeapOrder return (index - 1) / 2; \ } \ \ - FMOD size_t PFX##_l(size_t index) \ + FMOD size_t PFX##_impl_l(size_t index) \ { \ return 2 * index + 1; \ } \ \ - FMOD size_t PFX##_r(size_t index) \ + FMOD size_t PFX##_impl_r(size_t index) \ { \ return 2 * index + 2; \ } \ \ - FMOD bool PFX##_float_up(SNAME *_heap_, size_t index) \ + FMOD bool PFX##_impl_float_up(SNAME *_heap_, size_t index) \ { \ size_t C = index; \ V child = _heap_->buffer[C]; \ - V parent = _heap_->buffer[PFX##_p(C)]; \ + V parent = _heap_->buffer[PFX##_impl_p(C)]; \ \ int mod = _heap_->HO; \ \ while (C > 0 && _heap_->cmp(child, parent) * mod > 0) \ { \ V tmp = _heap_->buffer[C]; \ - _heap_->buffer[C] = _heap_->buffer[PFX##_p(C)]; \ - _heap_->buffer[PFX##_p(C)] = tmp; \ + _heap_->buffer[C] = _heap_->buffer[PFX##_impl_p(C)]; \ + _heap_->buffer[PFX##_impl_p(C)] = tmp; \ \ - C = PFX##_p(C); \ + C = PFX##_impl_p(C); \ \ child = _heap_->buffer[C]; \ - parent = _heap_->buffer[PFX##_p(C)]; \ + parent = _heap_->buffer[PFX##_impl_p(C)]; \ } \ \ return true; \ } \ \ - FMOD bool PFX##_float_down(SNAME *_heap_, size_t index) \ + FMOD bool PFX##_impl_float_down(SNAME *_heap_, size_t index) \ { \ int mod = _heap_->HO; \ \ while (index < _heap_->count) \ { \ - size_t L = PFX##_l(index); \ - size_t R = PFX##_r(index); \ + size_t L = PFX##_impl_l(index); \ + size_t R = PFX##_impl_r(index); \ size_t C = index; \ \ if (L < _heap_->count && _heap_->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) \ @@ -423,6 +470,26 @@ typedef enum HeapOrder } \ \ return true; \ + } \ + \ + SNAME##_iter PFX##_impl_it_start(SNAME *_heap_) \ + { \ + SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _heap_); \ + PFX##_iter_to_start(&iter); \ + \ + return iter; \ + } \ + \ + SNAME##_iter PFX##_impl_it_end(SNAME *_heap_) \ + { \ + SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _heap_); \ + PFX##_iter_to_end(&iter); \ + \ + return iter; \ } #endif /* CMC_HEAP_H */