fx.collections: update iterator semantics
This commit is contained in:
@@ -17,7 +17,7 @@ struct fx_array_p {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct fx_array_iterator_p {
|
struct fx_array_iterator_p {
|
||||||
fx_array *_a;
|
const fx_array *_a;
|
||||||
struct fx_array_p *_a_p;
|
struct fx_array_p *_a_p;
|
||||||
|
|
||||||
/** The index of the current value */
|
/** The index of the current value */
|
||||||
@@ -170,9 +170,7 @@ static fx_value array_get(struct fx_array_p *array, size_t at)
|
|||||||
return FX_VALUE_EMPTY;
|
return FX_VALUE_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_value result;
|
return fx_value_copy_return(array->ar_data[at]);
|
||||||
fx_value_copy(&result, &array->ar_data[at]);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t array_get_size(const struct fx_array_p *array)
|
static size_t array_get_size(const struct fx_array_p *array)
|
||||||
@@ -373,7 +371,7 @@ static fx_status array_to_string(
|
|||||||
|
|
||||||
/*** ITERATOR FUNCTIONS *******************************************************/
|
/*** ITERATOR FUNCTIONS *******************************************************/
|
||||||
|
|
||||||
static fx_iterator *iterable_begin(fx_object *obj)
|
static const fx_iterator *iterable_begin(const fx_object *obj)
|
||||||
{
|
{
|
||||||
fx_array_iterator *it_obj = fx_object_create(FX_TYPE_ARRAY_ITERATOR);
|
fx_array_iterator *it_obj = fx_object_create(FX_TYPE_ARRAY_ITERATOR);
|
||||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||||
@@ -437,7 +435,7 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
|||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value iterator_get_value(const fx_iterator *obj)
|
static const fx_value *iterator_get_value(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||||
obj,
|
obj,
|
||||||
@@ -445,10 +443,10 @@ static fx_value iterator_get_value(const fx_iterator *obj)
|
|||||||
struct fx_array_p *array = it->_a_p;
|
struct fx_array_p *array = it->_a_p;
|
||||||
|
|
||||||
if (it->i >= array->ar_len) {
|
if (it->i >= array->ar_len) {
|
||||||
return FX_VALUE_EMPTY;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *it->value;
|
return it->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fx_status iterator_is_valid(const fx_iterator *obj)
|
static enum fx_status iterator_is_valid(const fx_iterator *obj)
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ struct fx_hashmap_p {
|
|||||||
struct fx_hashmap_iterator_p {
|
struct fx_hashmap_iterator_p {
|
||||||
size_t i;
|
size_t i;
|
||||||
fx_hashmap_item item;
|
fx_hashmap_item item;
|
||||||
|
fx_value item_value;
|
||||||
|
|
||||||
fx_hashmap *_h;
|
const fx_hashmap *_h;
|
||||||
struct fx_hashmap_p *_h_p;
|
struct fx_hashmap_p *_h_p;
|
||||||
fx_bst_node *_cbn;
|
fx_bst_node *_cbn;
|
||||||
fx_queue_entry *_cqe;
|
fx_queue_entry *_cqe;
|
||||||
@@ -420,7 +421,7 @@ bool fx_hashmap_is_empty(const fx_hashmap *hashmap)
|
|||||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_HASHMAP, hashmap_is_empty, hashmap);
|
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_HASHMAP, hashmap_is_empty, hashmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_iterator *fx_hashmap_begin(fx_hashmap *hashmap)
|
const fx_iterator *fx_hashmap_begin(const fx_hashmap *hashmap)
|
||||||
{
|
{
|
||||||
fx_hashmap_iterator *it_obj = fx_object_create(
|
fx_hashmap_iterator *it_obj = fx_object_create(
|
||||||
FX_TYPE_HASHMAP_ITERATOR);
|
FX_TYPE_HASHMAP_ITERATOR);
|
||||||
@@ -617,12 +618,13 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
|||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value iterator_get_value(const fx_iterator *obj)
|
static const fx_value *iterator_get_value(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_hashmap_iterator_p *it = fx_object_get_private(
|
struct fx_hashmap_iterator_p *it = fx_object_get_private(
|
||||||
obj,
|
obj,
|
||||||
FX_TYPE_HASHMAP_ITERATOR);
|
FX_TYPE_HASHMAP_ITERATOR);
|
||||||
return FX_POINTER(&it->item);
|
it->item_value = FX_POINTER(&it->item);
|
||||||
|
return &it->item_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CLASS DEFINITION *********************************************************/
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
@@ -635,7 +637,6 @@ FX_TYPE_CLASS_BEGIN(fx_hashmap)
|
|||||||
|
|
||||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
|
||||||
FX_INTERFACE_ENTRY(it_begin) = fx_hashmap_begin;
|
FX_INTERFACE_ENTRY(it_begin) = fx_hashmap_begin;
|
||||||
FX_INTERFACE_ENTRY(it_cbegin) = fx_hashmap_cbegin;
|
|
||||||
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
||||||
FX_TYPE_CLASS_END(fx_hashmap)
|
FX_TYPE_CLASS_END(fx_hashmap)
|
||||||
|
|
||||||
|
|||||||
+115
-68
@@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <fx/collections/hashtable.h>
|
#include <fx/collections/hashtable.h>
|
||||||
#include <fx/misc.h>
|
#include <fx/misc.h>
|
||||||
#include <fx/reflection/property.h>
|
#include <fx/reflection/property.h>
|
||||||
@@ -47,8 +48,9 @@ struct fx_hashtable_p {
|
|||||||
struct fx_hashtable_iterator_p {
|
struct fx_hashtable_iterator_p {
|
||||||
size_t i;
|
size_t i;
|
||||||
fx_hashtable_item *item;
|
fx_hashtable_item *item;
|
||||||
|
fx_value item_value;
|
||||||
|
|
||||||
fx_hashtable *_h;
|
const fx_hashtable *_h;
|
||||||
struct fx_hashtable_p *_h_p;
|
struct fx_hashtable_p *_h_p;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,12 +69,14 @@ static fx_status convert_key_to_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t index = hash % table_size, i = 1;
|
size_t index = hash % table_size, i = 1;
|
||||||
while (table[index].i_item && i < table_size) {
|
bool index_found = false;
|
||||||
|
while (table[index].i_item && i <= table_size) {
|
||||||
const struct fx_hashtable_item_p *item = fx_object_get_private(
|
const struct fx_hashtable_item_p *item = fx_object_get_private(
|
||||||
table[index].i_item,
|
table[index].i_item,
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
FX_TYPE_HASHTABLE_ITEM);
|
||||||
int cmp = fx_value_compare(&item->i_key, v);
|
int cmp = fx_value_compare(&item->i_key, v);
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
|
index_found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +84,16 @@ static fx_status convert_key_to_index(
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!index_found) {
|
||||||
|
return FX_ERR_NO_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(index < table_size);
|
||||||
*out_index = index;
|
*out_index = index;
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_status find_key(
|
static fx_status allocate_index_for_key(
|
||||||
const fx_value *v,
|
const fx_value *v,
|
||||||
struct table_item *table,
|
struct table_item *table,
|
||||||
size_t table_size,
|
size_t table_size,
|
||||||
@@ -96,15 +105,12 @@ static fx_status find_key(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found = false;
|
size_t index = hash % table_size;
|
||||||
size_t index = hash % table_size, i = 1;
|
bool ok = false;
|
||||||
while (table[index].i_item && i < table_size) {
|
|
||||||
const struct fx_hashtable_item_p *item = fx_object_get_private(
|
for (size_t i = 1; i < table_size; i++) {
|
||||||
table[index].i_item,
|
if (!table[index].i_item) {
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
ok = true;
|
||||||
int cmp = fx_value_compare(&item->i_key, v);
|
|
||||||
if (cmp == 0) {
|
|
||||||
found = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +118,11 @@ static fx_status find_key(
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!ok) {
|
||||||
return FX_ERR_NO_ENTRY;
|
return FX_ERR_NO_SPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(index < table_size);
|
||||||
*out_index = index;
|
*out_index = index;
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -126,10 +133,9 @@ static fx_status add_item_to_table(
|
|||||||
size_t table_capacity)
|
size_t table_capacity)
|
||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
fx_status status = allocate_index_for_key(
|
||||||
fx_status status = convert_key_to_index(
|
|
||||||
&item_p->i_key,
|
&item_p->i_key,
|
||||||
table,
|
table,
|
||||||
table_capacity,
|
table_capacity,
|
||||||
@@ -231,29 +237,47 @@ static fx_status hashtable_put(
|
|||||||
if (!FX_OK(status)) {
|
if (!FX_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
capacity = primes[hashtable->t_max_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
status = convert_key_to_index(
|
do {
|
||||||
key,
|
status = allocate_index_for_key(
|
||||||
hashtable->t_items,
|
key,
|
||||||
capacity,
|
hashtable->t_items,
|
||||||
&index);
|
capacity,
|
||||||
if (!FX_OK(status)) {
|
&index);
|
||||||
return status;
|
if (status == FX_ERR_NO_SPACE) {
|
||||||
}
|
status = resize_table(
|
||||||
|
hashtable,
|
||||||
|
hashtable->t_max_index + 1);
|
||||||
|
if (!FX_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
capacity = primes[hashtable->t_max_index];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FX_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
fx_hashtable_item *item = fx_object_create(FX_TYPE_HASHTABLE_ITEM);
|
fx_hashtable_item *item = fx_object_create(FX_TYPE_HASHTABLE_ITEM);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return FX_ERR_NO_MEMORY;
|
return FX_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
|
||||||
fx_value_copy(&item_p->i_key, key);
|
fx_value_copy(&item_p->i_key, key);
|
||||||
fx_value_copy(&item_p->i_value, value);
|
fx_value_copy(&item_p->i_value, value);
|
||||||
|
|
||||||
|
assert(hashtable->t_items[index].i_item == NULL);
|
||||||
hashtable->t_items[index].i_item = item;
|
hashtable->t_items[index].i_item = item;
|
||||||
hashtable->t_count++;
|
hashtable->t_count++;
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
@@ -279,9 +303,8 @@ static const fx_value *hashtable_get(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
const struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
|
||||||
return &item_p->i_value;
|
return &item_p->i_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,14 +318,16 @@ static bool hashtable_is_empty(const struct fx_hashtable_p *hashtable)
|
|||||||
return hashtable->t_count == 0;
|
return hashtable->t_count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value hashtable_item_get_key(const struct fx_hashtable_item_p *item)
|
static const fx_value *hashtable_item_get_key(
|
||||||
|
const struct fx_hashtable_item_p *item)
|
||||||
{
|
{
|
||||||
return item->i_key;
|
return &item->i_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value hashtable_item_get_value(const struct fx_hashtable_item_p *item)
|
static const fx_value *hashtable_item_get_value(
|
||||||
|
const struct fx_hashtable_item_p *item)
|
||||||
{
|
{
|
||||||
return item->i_value;
|
return &item->i_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** PUBLIC FUNCTIONS *********************************************************/
|
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||||
@@ -347,7 +372,7 @@ bool fx_hashtable_is_empty(const fx_hashtable *hashtable)
|
|||||||
hashtable);
|
hashtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_value fx_hashtable_item_get_key(const fx_hashtable_item *item)
|
const fx_value *fx_hashtable_item_get_key(const fx_hashtable_item *item)
|
||||||
{
|
{
|
||||||
FX_CLASS_DISPATCH_STATIC_0(
|
FX_CLASS_DISPATCH_STATIC_0(
|
||||||
FX_TYPE_HASHTABLE_ITEM,
|
FX_TYPE_HASHTABLE_ITEM,
|
||||||
@@ -355,7 +380,7 @@ fx_value fx_hashtable_item_get_key(const fx_hashtable_item *item)
|
|||||||
item);
|
item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_value fx_hashtable_item_get_value(const fx_hashtable_item *item)
|
const fx_value *fx_hashtable_item_get_value(const fx_hashtable_item *item)
|
||||||
{
|
{
|
||||||
FX_CLASS_DISPATCH_STATIC_0(
|
FX_CLASS_DISPATCH_STATIC_0(
|
||||||
FX_TYPE_HASHTABLE_ITEM,
|
FX_TYPE_HASHTABLE_ITEM,
|
||||||
@@ -363,13 +388,12 @@ fx_value fx_hashtable_item_get_value(const fx_hashtable_item *item)
|
|||||||
item);
|
item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_iterator *fx_hashtable_begin(fx_hashtable *hashtable)
|
const fx_iterator *fx_hashtable_begin(const fx_hashtable *hashtable)
|
||||||
{
|
{
|
||||||
fx_hashtable_iterator *it_obj = fx_object_create(
|
fx_hashtable_iterator *it_obj
|
||||||
FX_TYPE_HASHTABLE_ITERATOR);
|
= fx_object_create(FX_TYPE_HASHTABLE_ITERATOR);
|
||||||
struct fx_hashtable_iterator_p *it = fx_object_get_private(
|
struct fx_hashtable_iterator_p *it
|
||||||
it_obj,
|
= fx_object_get_private(it_obj, FX_TYPE_HASHTABLE_ITERATOR);
|
||||||
FX_TYPE_HASHTABLE_ITERATOR);
|
|
||||||
|
|
||||||
it->_h = hashtable;
|
it->_h = hashtable;
|
||||||
it->_h_p = fx_object_get_private(hashtable, FX_TYPE_HASHTABLE);
|
it->_h_p = fx_object_get_private(hashtable, FX_TYPE_HASHTABLE);
|
||||||
@@ -387,6 +411,7 @@ fx_iterator *fx_hashtable_begin(fx_hashtable *hashtable)
|
|||||||
it->i++;
|
it->i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it->item_value = FX_VALUE_OBJECT_REF(table[it->i].i_item);
|
||||||
return it_obj;
|
return it_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,6 +430,30 @@ static void hashtable_init(fx_object *obj, void *priv)
|
|||||||
static void hashtable_fini(fx_object *obj, void *priv)
|
static void hashtable_fini(fx_object *obj, void *priv)
|
||||||
{
|
{
|
||||||
struct fx_hashtable_p *map = priv;
|
struct fx_hashtable_p *map = priv;
|
||||||
|
|
||||||
|
size_t capacity = primes[map->t_max_index];
|
||||||
|
size_t nr_destroyed = 0;
|
||||||
|
for (size_t i = 0; i < capacity; i++) {
|
||||||
|
if (map->t_items[i].i_item) {
|
||||||
|
nr_destroyed++;
|
||||||
|
fx_hashtable_item_unref(map->t_items[i].i_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(map->t_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hashtable_item_fini(fx_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct fx_hashtable_item_p *item = priv;
|
||||||
|
fx_value_unset(&item->i_key);
|
||||||
|
fx_value_unset(&item->i_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hashtable_iterator_fini(fx_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct fx_hashtable_iterator_p *it = priv;
|
||||||
|
fx_value_unset(&it->item_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_status to_string(
|
static fx_status to_string(
|
||||||
@@ -412,9 +461,8 @@ static fx_status to_string(
|
|||||||
fx_stream *out,
|
fx_stream *out,
|
||||||
const char *format)
|
const char *format)
|
||||||
{
|
{
|
||||||
struct fx_hashtable_p *hashtable = fx_object_get_private(
|
struct fx_hashtable_p *hashtable
|
||||||
obj->v_object,
|
= fx_object_get_private(obj->v_object, FX_TYPE_HASHTABLE);
|
||||||
FX_TYPE_HASHTABLE);
|
|
||||||
|
|
||||||
if (!hashtable->t_count) {
|
if (!hashtable->t_count) {
|
||||||
fx_stream_write_cstr(out, "{}", NULL);
|
fx_stream_write_cstr(out, "{}", NULL);
|
||||||
@@ -434,9 +482,8 @@ static fx_status to_string(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nr_written++;
|
nr_written++;
|
||||||
struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
|
||||||
|
|
||||||
const char *cstr = NULL;
|
const char *cstr = NULL;
|
||||||
fx_value_get_cstr(&item_p->i_key, &cstr);
|
fx_value_get_cstr(&item_p->i_key, &cstr);
|
||||||
@@ -487,9 +534,8 @@ static fx_status get_key(
|
|||||||
return FX_ERR_NOT_SUPPORTED;
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
|
||||||
fx_value_copy(out, &item_p->i_key);
|
fx_value_copy(out, &item_p->i_key);
|
||||||
|
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
@@ -506,9 +552,8 @@ static fx_status get_value(
|
|||||||
return FX_ERR_NOT_SUPPORTED;
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_hashtable_item_p *item_p = fx_object_get_private(
|
struct fx_hashtable_item_p *item_p
|
||||||
item,
|
= fx_object_get_private(item, FX_TYPE_HASHTABLE_ITEM);
|
||||||
FX_TYPE_HASHTABLE_ITEM);
|
|
||||||
fx_value_copy(out, &item_p->i_value);
|
fx_value_copy(out, &item_p->i_value);
|
||||||
|
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
@@ -518,9 +563,10 @@ static fx_status get_value(
|
|||||||
|
|
||||||
static enum fx_status iterator_move_next(const fx_iterator *obj)
|
static enum fx_status iterator_move_next(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_hashtable_iterator_p *it = fx_object_get_private(
|
struct fx_hashtable_iterator_p *it
|
||||||
obj,
|
= fx_object_get_private(obj, FX_TYPE_HASHTABLE_ITERATOR);
|
||||||
FX_TYPE_HASHTABLE_ITERATOR);
|
|
||||||
|
fx_value_unset(&it->item_value);
|
||||||
struct table_item *table = it->_h_p->t_items;
|
struct table_item *table = it->_h_p->t_items;
|
||||||
size_t capacity = primes[it->_h_p->t_max_index];
|
size_t capacity = primes[it->_h_p->t_max_index];
|
||||||
|
|
||||||
@@ -533,14 +579,14 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
|
|||||||
return FX_ERR_NO_DATA;
|
return FX_ERR_NO_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it->item_value = FX_VALUE_OBJECT_REF(table[it->i].i_item);
|
||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fx_status iterator_erase(fx_iterator *obj)
|
static enum fx_status iterator_erase(fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_hashtable_iterator_p *it = fx_object_get_private(
|
struct fx_hashtable_iterator_p *it
|
||||||
obj,
|
= fx_object_get_private(obj, FX_TYPE_HASHTABLE_ITERATOR);
|
||||||
FX_TYPE_HASHTABLE_ITERATOR);
|
|
||||||
|
|
||||||
struct table_item *table = it->_h_p->t_items;
|
struct table_item *table = it->_h_p->t_items;
|
||||||
size_t capacity = primes[it->_h_p->t_max_index];
|
size_t capacity = primes[it->_h_p->t_max_index];
|
||||||
@@ -562,19 +608,18 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
|||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value iterator_get_value(const fx_iterator *obj)
|
static const fx_value *iterator_get_value(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_hashtable_iterator_p *it = fx_object_get_private(
|
struct fx_hashtable_iterator_p *it
|
||||||
obj,
|
= fx_object_get_private(obj, FX_TYPE_HASHTABLE_ITERATOR);
|
||||||
FX_TYPE_HASHTABLE_ITERATOR);
|
|
||||||
struct table_item *table = it->_h_p->t_items;
|
struct table_item *table = it->_h_p->t_items;
|
||||||
size_t capacity = primes[it->_h_p->t_max_index];
|
size_t capacity = primes[it->_h_p->t_max_index];
|
||||||
|
|
||||||
if (table[it->i].i_item) {
|
if (table[it->i].i_item) {
|
||||||
return FX_VALUE_OBJECT(table[it->i].i_item);
|
return &it->item_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FX_VALUE_EMPTY;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CLASS DEFINITION *********************************************************/
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
@@ -619,6 +664,7 @@ FX_TYPE_DEFINITION_BEGIN(fx_hashtable_iterator)
|
|||||||
FX_TYPE_EXTENDS(FX_TYPE_ITERATOR);
|
FX_TYPE_EXTENDS(FX_TYPE_ITERATOR);
|
||||||
FX_TYPE_CLASS(fx_hashtable_iterator_class);
|
FX_TYPE_CLASS(fx_hashtable_iterator_class);
|
||||||
FX_TYPE_INSTANCE_PRIVATE(struct fx_hashtable_iterator_p);
|
FX_TYPE_INSTANCE_PRIVATE(struct fx_hashtable_iterator_p);
|
||||||
|
FX_TYPE_INSTANCE_FINI(hashtable_iterator_fini);
|
||||||
FX_TYPE_DEFINITION_END(fx_hashtable_iterator)
|
FX_TYPE_DEFINITION_END(fx_hashtable_iterator)
|
||||||
|
|
||||||
// ---- fx_hashtable_item DEFINITION
|
// ---- fx_hashtable_item DEFINITION
|
||||||
@@ -637,4 +683,5 @@ FX_TYPE_DEFINITION_BEGIN(fx_hashtable_item)
|
|||||||
FX_TYPE_EXTENDS(FX_TYPE_OBJECT);
|
FX_TYPE_EXTENDS(FX_TYPE_OBJECT);
|
||||||
FX_TYPE_CLASS(fx_hashtable_item_class);
|
FX_TYPE_CLASS(fx_hashtable_item_class);
|
||||||
FX_TYPE_INSTANCE_PRIVATE(struct fx_hashtable_item_p);
|
FX_TYPE_INSTANCE_PRIVATE(struct fx_hashtable_item_p);
|
||||||
|
FX_TYPE_INSTANCE_FINI(hashtable_item_fini);
|
||||||
FX_TYPE_DEFINITION_END(fx_hashtable_item)
|
FX_TYPE_DEFINITION_END(fx_hashtable_item)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ FX_API bool fx_hashmap_has_key(
|
|||||||
FX_API size_t fx_hashmap_get_size(const fx_hashmap *hashmap);
|
FX_API size_t fx_hashmap_get_size(const fx_hashmap *hashmap);
|
||||||
FX_API bool fx_hashmap_is_empty(const fx_hashmap *hashmap);
|
FX_API bool fx_hashmap_is_empty(const fx_hashmap *hashmap);
|
||||||
|
|
||||||
FX_API fx_iterator *fx_hashmap_begin(fx_hashmap *hashmap);
|
FX_API const fx_iterator *fx_hashmap_begin(const fx_hashmap *hashmap);
|
||||||
FX_API const fx_iterator *fx_hashmap_cbegin(const fx_hashmap *hashmap);
|
FX_API const fx_iterator *fx_hashmap_cbegin(const fx_hashmap *hashmap);
|
||||||
|
|
||||||
FX_DECLS_END;
|
FX_DECLS_END;
|
||||||
|
|||||||
@@ -45,10 +45,11 @@ FX_API const fx_value *fx_hashtable_get(
|
|||||||
FX_API size_t fx_hashtable_get_count(const fx_hashtable *hashtable);
|
FX_API size_t fx_hashtable_get_count(const fx_hashtable *hashtable);
|
||||||
FX_API bool fx_hashtable_is_empty(const fx_hashtable *hashtable);
|
FX_API bool fx_hashtable_is_empty(const fx_hashtable *hashtable);
|
||||||
|
|
||||||
FX_API fx_iterator *fx_hashtable_begin(fx_hashtable *hashtable);
|
FX_API const fx_iterator *fx_hashtable_begin(const fx_hashtable *hashtable);
|
||||||
|
|
||||||
FX_API fx_value fx_hashtable_item_get_key(const fx_hashtable_item *item);
|
FX_API const fx_value *fx_hashtable_item_get_key(const fx_hashtable_item *item);
|
||||||
FX_API fx_value fx_hashtable_item_get_value(const fx_hashtable_item *item);
|
FX_API const fx_value *fx_hashtable_item_get_value(
|
||||||
|
const fx_hashtable_item *item);
|
||||||
|
|
||||||
FX_DECLS_END;
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ FX_API void fx_list_delete_all(fx_list *q);
|
|||||||
|
|
||||||
FX_API void *fx_list_entry_value(const fx_list_entry *entry);
|
FX_API void *fx_list_entry_value(const fx_list_entry *entry);
|
||||||
|
|
||||||
FX_API fx_iterator *fx_list_begin(fx_list *q);
|
FX_API const fx_iterator *fx_list_begin(const fx_list *q);
|
||||||
FX_API const fx_iterator *fx_list_cbegin(const fx_list *q);
|
|
||||||
|
|
||||||
FX_DECLS_END;
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
|||||||
+5
-24
@@ -23,6 +23,7 @@ struct fx_list_iterator_p {
|
|||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
void *item;
|
void *item;
|
||||||
|
fx_value item_value;
|
||||||
fx_list_entry *entry;
|
fx_list_entry *entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -401,27 +402,7 @@ void *fx_list_entry_value(const struct fx_list_entry *entry)
|
|||||||
return entry ? entry->e_data : NULL;
|
return entry ? entry->e_data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_iterator *fx_list_begin(fx_list *q)
|
const fx_iterator *fx_list_begin(const fx_list *q)
|
||||||
{
|
|
||||||
fx_list_iterator *it_obj = fx_object_create(FX_TYPE_LIST_ITERATOR);
|
|
||||||
struct fx_list_iterator_p *it = fx_object_get_private(
|
|
||||||
it_obj,
|
|
||||||
FX_TYPE_LIST_ITERATOR);
|
|
||||||
|
|
||||||
it->_q = q;
|
|
||||||
it->_q_p = fx_object_get_private(q, FX_TYPE_LIST);
|
|
||||||
it->_q_entry = fx_queue_first(&it->_q_p->l_queue);
|
|
||||||
|
|
||||||
it->i = 0;
|
|
||||||
it->entry = fx_unbox(struct fx_list_entry, it->_q_entry, e_entry);
|
|
||||||
if (it->entry) {
|
|
||||||
it->item = it->entry->e_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fx_iterator *fx_list_cbegin(const fx_list *q)
|
|
||||||
{
|
{
|
||||||
fx_list_iterator *it_obj = fx_object_create(FX_TYPE_LIST_ITERATOR);
|
fx_list_iterator *it_obj = fx_object_create(FX_TYPE_LIST_ITERATOR);
|
||||||
struct fx_list_iterator_p *it = fx_object_get_private(
|
struct fx_list_iterator_p *it = fx_object_get_private(
|
||||||
@@ -508,13 +489,14 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
|||||||
return FX_SUCCESS;
|
return FX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fx_value iterator_get_value(const fx_iterator *obj)
|
static const fx_value *iterator_get_value(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_list_iterator_p *it = fx_object_get_private(
|
struct fx_list_iterator_p *it = fx_object_get_private(
|
||||||
obj,
|
obj,
|
||||||
FX_TYPE_LIST_ITERATOR);
|
FX_TYPE_LIST_ITERATOR);
|
||||||
|
|
||||||
return FX_POINTER(it->item);
|
it->item_value = FX_POINTER(it->item);
|
||||||
|
return &it->item_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CLASS DEFINITION *********************************************************/
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
@@ -527,7 +509,6 @@ FX_TYPE_CLASS_BEGIN(fx_list)
|
|||||||
|
|
||||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
|
||||||
FX_INTERFACE_ENTRY(it_begin) = fx_list_begin;
|
FX_INTERFACE_ENTRY(it_begin) = fx_list_begin;
|
||||||
FX_INTERFACE_ENTRY(it_cbegin) = fx_list_cbegin;
|
|
||||||
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
||||||
FX_TYPE_CLASS_END(fx_list)
|
FX_TYPE_CLASS_END(fx_list)
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ int main(void)
|
|||||||
printf("no value\n");
|
printf("no value\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_iterator *it = fx_hashtable_begin(ht);
|
const fx_iterator *it = fx_hashtable_begin(ht);
|
||||||
fx_foreach(val, it)
|
fx_foreach(val, it)
|
||||||
{
|
{
|
||||||
fx_hashtable_item *item = NULL;
|
fx_hashtable_item *item = NULL;
|
||||||
fx_value_get_object(&val, &item);
|
fx_value_get_object(val, &item);
|
||||||
printf("item %p\n", item);
|
printf("item %p\n", item);
|
||||||
fx_value key, value;
|
const fx_value *key, *value;
|
||||||
key = fx_hashtable_item_get_key(item);
|
key = fx_hashtable_item_get_key(item);
|
||||||
value = fx_hashtable_item_get_value(item);
|
value = fx_hashtable_item_get_value(item);
|
||||||
|
|
||||||
@@ -34,10 +34,10 @@ int main(void)
|
|||||||
fx_foreach(prop_val, prop_it)
|
fx_foreach(prop_val, prop_it)
|
||||||
{
|
{
|
||||||
fx_property *prop;
|
fx_property *prop;
|
||||||
fx_value_get_object(&prop_val, &prop);
|
fx_value_get_object(prop_val, &prop);
|
||||||
printf("%s = ", fx_property_get_name(prop));
|
printf("%s = ", fx_property_get_name(prop));
|
||||||
fx_value value = FX_VALUE_EMPTY;
|
fx_value value = FX_VALUE_EMPTY;
|
||||||
fx_property_get_value(prop, &val, &value);
|
fx_property_get_value(prop, val, &value);
|
||||||
fx_value_to_string(&value, fx_stdout, NULL);
|
fx_value_to_string(&value, fx_stdout, NULL);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user