Updated table to simplify iteration. Iterated.
This commit is contained in:
parent
659ea490e2
commit
60671ccb47
@ -74,7 +74,7 @@ gperf := gperf
|
|||||||
|
|
||||||
target := # -mwindows
|
target := # -mwindows
|
||||||
optimize := -ffast-math
|
optimize := -ffast-math
|
||||||
warnbasic := -Wall -pedantic -ansi # -std=c99
|
warnbasic := -Wall -pedantic #-ansi # -std=c99
|
||||||
# Some stuff is really new.
|
# Some stuff is really new.
|
||||||
warnclang := -Wextra \
|
warnclang := -Wextra \
|
||||||
-Weverything \
|
-Weverything \
|
||||||
|
@ -269,6 +269,7 @@ static void words_to_string(const union kjvcite x, char (*const a)[12])
|
|||||||
#define TABLE_KEY union kjvcite
|
#define TABLE_KEY union kjvcite
|
||||||
#define TABLE_UINT uint32_t
|
#define TABLE_UINT uint32_t
|
||||||
#define TABLE_VALUE unsigned
|
#define TABLE_VALUE unsigned
|
||||||
|
#define TABLE_DEFUALT 0
|
||||||
#define TABLE_INVERSE
|
#define TABLE_INVERSE
|
||||||
#define TABLE_TO_STRING
|
#define TABLE_TO_STRING
|
||||||
#include "../src/table.h"
|
#include "../src/table.h"
|
||||||
@ -338,6 +339,17 @@ int main(void) {
|
|||||||
printf("words: %s\n", words_table_to_string(&words));
|
printf("words: %s\n", words_table_to_string(&words));
|
||||||
|
|
||||||
printf("kjv: %zu words\n", cum_words);
|
printf("kjv: %zu words\n", cum_words);
|
||||||
|
{
|
||||||
|
union kjvcite c;
|
||||||
|
struct words_table_iterator it = words_table_begin(&words);
|
||||||
|
unsigned *w;
|
||||||
|
while(words_table_next(&it, &c, &w))
|
||||||
|
printf("%s %u:%u -> %u\n",
|
||||||
|
kjv_book_string[c.book], c.chapter, c.verse, *w);
|
||||||
|
c.u32 = 0; /* Unnecessary? */
|
||||||
|
c.book = Genesis, c.chapter = 1, c.verse = 1;
|
||||||
|
printf("%u\n", words_table_get_or(&words, c, 0)); /* Why not get? */
|
||||||
|
}
|
||||||
goto finally;
|
goto finally;
|
||||||
catch:
|
catch:
|
||||||
success = EXIT_FAILURE;
|
success = EXIT_FAILURE;
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
It must be supplied <typedef:<PN>hash_fn> `<N>hash` and,
|
It must be supplied <typedef:<PN>hash_fn> `<N>hash` and,
|
||||||
<typedef:<PN>is_equal_fn> `<N>is_equal` or <typedef:<PN>unhash_fn> `<N>unhash`.
|
<typedef:<PN>is_equal_fn> `<N>is_equal` or <typedef:<PN>unhash_fn> `<N>unhash`.
|
||||||
|
|
||||||
|
(Fixme: remove entry as public struct, this should be entirely private.)
|
||||||
|
|
||||||
@param[TABLE_NAME, TABLE_KEY]
|
@param[TABLE_NAME, TABLE_KEY]
|
||||||
`<N>` that satisfies `C` naming conventions when mangled and a valid
|
`<N>` that satisfies `C` naming conventions when mangled and a valid
|
||||||
<typedef:<PN>key> associated therewith; required. `<PN>` is private, whose
|
<typedef:<PN>key> associated therewith; required. `<PN>` is private, whose
|
||||||
@ -607,40 +609,28 @@ static void N_(table_)(struct N_(table) *const table)
|
|||||||
static struct N_(table_iterator) N_(table_begin)(struct N_(table) *const
|
static struct N_(table_iterator) N_(table_begin)(struct N_(table) *const
|
||||||
table) { struct N_(table_iterator) it; it._ = PN_(iterator)(table);
|
table) { struct N_(table_iterator) it; it._ = PN_(iterator)(table);
|
||||||
return it; }
|
return it; }
|
||||||
/** Advances `it`. The awkwardness of this function because <typedef:<PN>entry>
|
#ifdef TABLE_VALUE /* <!-- map */
|
||||||
is not necessarily nullifyable, so we are not guaranteed to have an
|
/** Advances `it`. @param[key, value] If non-null, the key or value is filled
|
||||||
out-of-band entry to indicate completion. (May be changed in the future.)
|
with the next element on return true. `value` is a pointer to the actual value
|
||||||
@param[entry] If non-null, the entry is filled with the next element only if
|
in the map, only there if it is a map.
|
||||||
it has a next. @return Whether it had a next element. @allow */
|
@return Whether it had a next element. @allow */
|
||||||
static int N_(table_next)(struct N_(table_iterator) *const it,
|
static int N_(table_next)(struct N_(table_iterator) *const it,
|
||||||
PN_(entry) *entry) {
|
PN_(key) *key, PN_(value) **value) {
|
||||||
struct PN_(bucket) *b = PN_(next)(&it->_);
|
struct PN_(bucket) *bucket = PN_(next)(&it->_);
|
||||||
if(!b) return 0;
|
if(!bucket) return 0;
|
||||||
if(entry) *entry = PN_(to_entry)(b);
|
if(key) *key = PN_(bucket_key)(bucket);
|
||||||
|
if(value) *value = &bucket->value;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/** Especially for tables that can have zero as a valid value, this is used to
|
#else /* map --><!-- set */
|
||||||
differentiate between zero and null.
|
/** Advances `it`, sets `key` on true. */
|
||||||
@return Whether the table specified to `it` in <fn:<N>table_begin> has a
|
static int N_(table_next)(struct N_(table_iterator) *const it, PN_(key) *key) {
|
||||||
next element. @order Amortized on the capacity, \O(1). @allow */
|
struct PN_(bucket) *bucket = PN_(next)(&it->_);
|
||||||
static int N_(table_has_next)(struct N_(table_iterator) *const it) {
|
if(!bucket) return 0;
|
||||||
assert(it);
|
if(key) *key = PN_(bucket_key)(bucket);
|
||||||
return it->_.table && it->_.table->buckets && PN_(skip)(&it->_);
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef TABLE_VALUE /* <!-- value */
|
#endif /* set --> */
|
||||||
/** Defined if `TABLE_VALUE`. Advances `it` only when <fn:<N>table_has_next>.
|
|
||||||
@return The next key. @allow */
|
|
||||||
static PN_(key) N_(table_next_key)(struct N_(table_iterator) *const it) {
|
|
||||||
struct PN_(bucket) *b = PN_(next)(&it->_);
|
|
||||||
return PN_(bucket_key)(b);
|
|
||||||
}
|
|
||||||
/** Defined if `TABLE_VALUE`. Advances `it` only when <fn:<N>table_has_next>.
|
|
||||||
@return The next value. @allow */
|
|
||||||
static PN_(value) N_(table_next_value)(struct N_(table_iterator) *const it) {
|
|
||||||
struct PN_(bucket) *b = PN_(next)(&it->_);
|
|
||||||
return b->value;
|
|
||||||
}
|
|
||||||
#endif /* value --> */
|
|
||||||
/** Removes the entry at `it`. Whereas <fn:<N>table_remove> invalidates the
|
/** Removes the entry at `it`. Whereas <fn:<N>table_remove> invalidates the
|
||||||
iterator, this corrects for a signal `it`.
|
iterator, this corrects for a signal `it`.
|
||||||
@return Success, or there was no entry at the iterator's position, (anymore.)
|
@return Success, or there was no entry at the iterator's position, (anymore.)
|
||||||
@ -825,14 +815,15 @@ static void PN_(unused_base)(void) {
|
|||||||
PN_(entry) e; PN_(key) k; PN_(value) v;
|
PN_(entry) e; PN_(key) k; PN_(value) v;
|
||||||
memset(&e, 0, sizeof e); memset(&k, 0, sizeof k); memset(&v, 0, sizeof v);
|
memset(&e, 0, sizeof e); memset(&k, 0, sizeof k); memset(&v, 0, sizeof v);
|
||||||
PN_(is_element)(0);
|
PN_(is_element)(0);
|
||||||
N_(table)(); N_(table_)(0); N_(table_begin)(0); N_(table_next)(0, 0);
|
N_(table)(); N_(table_)(0); N_(table_begin)(0);
|
||||||
N_(table_buffer)(0, 0); N_(table_clear)(0); N_(table_is)(0, k);
|
N_(table_buffer)(0, 0); N_(table_clear)(0); N_(table_is)(0, k);
|
||||||
N_(table_query)(0, k, 0); N_(table_get_or)(0, k, v); N_(table_try)(0, e);
|
N_(table_query)(0, k, 0); N_(table_get_or)(0, k, v); N_(table_try)(0, e);
|
||||||
N_(table_update)(0, e, 0); N_(table_policy)(0,e,0,0);
|
N_(table_update)(0, e, 0); N_(table_policy)(0,e,0,0);
|
||||||
N_(table_remove)(0, k); N_(table_begin)(0); N_(table_next)(0, 0);
|
N_(table_remove)(0, k); N_(table_iterator_remove)(0);
|
||||||
N_(table_has_next)(0); N_(table_iterator_remove)(0);
|
|
||||||
#ifdef TABLE_VALUE
|
#ifdef TABLE_VALUE
|
||||||
N_(table_assign)(0, k, 0); N_(table_next_key)(0); N_(table_next_value)(0);
|
N_(table_next)(0, 0, 0); N_(table_assign)(0, k, 0);
|
||||||
|
#else
|
||||||
|
N_(table_next)(0, 0);
|
||||||
#endif
|
#endif
|
||||||
PN_(unused_base_coda)();
|
PN_(unused_base_coda)();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user