diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2013-10-28 12:35:37 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2013-10-28 12:35:37 +0000 |
| commit | 151f86c1e9e518c34a76ff5fdab9afd34000fe0d (patch) | |
| tree | 5d16b65e0abaae250f83e48b7bb849fce79180ba /src/runtime/c/gu | |
| parent | cd5a0de253152b9aa484b6c684d9943094ac87dc (diff) | |
fix the handling of 'pre' in the C runtime
Diffstat (limited to 'src/runtime/c/gu')
| -rw-r--r-- | src/runtime/c/gu/seq.c | 34 | ||||
| -rw-r--r-- | src/runtime/c/gu/seq.h | 13 |
2 files changed, 40 insertions, 7 deletions
diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index b798d2923..8ec6480cc 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -255,7 +255,7 @@ gu_buf_sort(GuBuf *buf, GuOrder *order) } void* -gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_offset, void *key) +gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, void *key) { size_t i = 0; size_t j = seq->len-1; @@ -263,8 +263,8 @@ gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_off while (i <= j) { size_t k = (i+j) / 2; uint8_t* elem_p = &seq->data[elem_size * k]; - int cmp = order->compare(order, key, elem_p + field_offset); - + int cmp = order->compare(order, key, elem_p); + if (cmp < 0) { j = k-1; } else if (cmp > 0) { @@ -273,10 +273,36 @@ gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_off return elem_p; } } - + return NULL; } +bool +gu_seq_binsearch_index_(GuSeq *seq, GuOrder *order, size_t elem_size, + void *key, size_t *pindex) +{ + size_t i = 0; + size_t j = seq->len-1; + + while (i <= j) { + size_t k = (i+j) / 2; + uint8_t* elem_p = &seq->data[elem_size * k]; + int cmp = order->compare(order, key, elem_p); + + if (cmp < 0) { + j = k-1; + } else if (cmp > 0) { + i = k+1; + } else { + *pindex = k; + return true; + } + } + + *pindex = j; + return false; +} + static void gu_heap_siftdown(GuBuf *buf, GuOrder *order, const void *value, int startpos, int pos) diff --git a/src/runtime/c/gu/seq.h b/src/runtime/c/gu/seq.h index cb18a90b5..2b0020bab 100644 --- a/src/runtime/c/gu/seq.h +++ b/src/runtime/c/gu/seq.h @@ -114,11 +114,18 @@ gu_seq_resize_tail(GuSeq seq, ptrdiff_t change); void gu_buf_sort(GuBuf *buf, GuOrder *order); -#define gu_seq_binsearch(S, O, T, N, V) \ - ((T*) gu_seq_binsearch_(S, O, sizeof(T), offsetof(T,N), V)) +#define gu_seq_binsearch(S, O, T, V) \ + ((T*) gu_seq_binsearch_(S, O, sizeof(T), V)) void* -gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_offset, void *key); +gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, void *key); + +#define gu_seq_binsearch_index(S, O, T, V, PI) \ + gu_seq_binsearch_index_(S, O, sizeof(T), V, PI) + +bool +gu_seq_binsearch_index_(GuSeq *seq, GuOrder *order, size_t elem_size, + void *key, size_t *pindex); // Using a buffer as a heap void |
