diff options
Diffstat (limited to 'gee/mapiterator.c')
-rw-r--r-- | gee/mapiterator.c | 238 |
1 files changed, 221 insertions, 17 deletions
diff --git a/gee/mapiterator.c b/gee/mapiterator.c index 82d133b..f7f2b1e 100644 --- a/gee/mapiterator.c +++ b/gee/mapiterator.c @@ -4,6 +4,7 @@ /* mapiterator.vala * * Copyright (C) 2009 Didier Villevalois + * Copyright (C) 2011 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,16 +35,29 @@ typedef struct _GeeMapIterator GeeMapIterator; typedef struct _GeeMapIteratorIface GeeMapIteratorIface; +#define _a_destroy_func0(var) (((var == NULL) || (a_destroy_func == NULL)) ? NULL : (var = (a_destroy_func (var), NULL))) +typedef gpointer (*GeeFoldMapFunc) (gconstpointer k, gconstpointer v, gpointer a, void* user_data); +typedef gboolean (*GeeForallMapFunc) (gconstpointer k, gconstpointer v, void* user_data); struct _GeeMapIteratorIface { GTypeInterface parent_iface; + GType (*get_k_type) (GeeMapIterator* self); + GBoxedCopyFunc (*get_k_dup_func) (GeeMapIterator* self); + GDestroyNotify (*get_k_destroy_func) (GeeMapIterator* self); + GType (*get_v_type) (GeeMapIterator* self); + GBoxedCopyFunc (*get_v_dup_func) (GeeMapIterator* self); + GDestroyNotify (*get_v_destroy_func) (GeeMapIterator* self); gboolean (*next) (GeeMapIterator* self); gboolean (*has_next) (GeeMapIterator* self); - gboolean (*first) (GeeMapIterator* self); gpointer (*get_key) (GeeMapIterator* self); gpointer (*get_value) (GeeMapIterator* self); void (*set_value) (GeeMapIterator* self, gconstpointer value); void (*unset) (GeeMapIterator* self); + gpointer (*fold) (GeeMapIterator* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldMapFunc f, void* f_target, gpointer seed); + gboolean (*foreach) (GeeMapIterator* self, GeeForallMapFunc f, void* f_target); + gboolean (*get_valid) (GeeMapIterator* self); + gboolean (*get_mutable) (GeeMapIterator* self); + gboolean (*get_read_only) (GeeMapIterator* self); }; @@ -51,11 +65,17 @@ struct _GeeMapIteratorIface { GType gee_map_iterator_get_type (void) G_GNUC_CONST; gboolean gee_map_iterator_next (GeeMapIterator* self); gboolean gee_map_iterator_has_next (GeeMapIterator* self); -gboolean gee_map_iterator_first (GeeMapIterator* self); gpointer gee_map_iterator_get_key (GeeMapIterator* self); gpointer gee_map_iterator_get_value (GeeMapIterator* self); void gee_map_iterator_set_value (GeeMapIterator* self, gconstpointer value); void gee_map_iterator_unset (GeeMapIterator* self); +gpointer gee_map_iterator_fold (GeeMapIterator* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldMapFunc f, void* f_target, gpointer seed); +static gpointer gee_map_iterator_real_fold (GeeMapIterator* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldMapFunc f, void* f_target, gpointer seed); +gboolean gee_map_iterator_get_valid (GeeMapIterator* self); +gboolean gee_map_iterator_foreach (GeeMapIterator* self, GeeForallMapFunc f, void* f_target); +static gboolean gee_map_iterator_real_foreach (GeeMapIterator* self, GeeForallMapFunc f, void* f_target); +gboolean gee_map_iterator_get_mutable (GeeMapIterator* self); +gboolean gee_map_iterator_get_read_only (GeeMapIterator* self); /** @@ -81,17 +101,6 @@ gboolean gee_map_iterator_has_next (GeeMapIterator* self) { /** - * Rewinds to the first entry in the iteration. - * - * @return ``true`` if the iterator has a first entry - */ -gboolean gee_map_iterator_first (GeeMapIterator* self) { - g_return_val_if_fail (self != NULL, FALSE); - return GEE_MAP_ITERATOR_GET_INTERFACE (self)->first (self); -} - - -/** * Returns the current key in the iteration. * * @return the current key in the iteration @@ -128,7 +137,7 @@ void gee_map_iterator_set_value (GeeMapIterator* self, gconstpointer value) { * Unsets the current entry in the iteration. The cursor is set in an * in-between state. {@link get_key}, {@link get_value}, {@link set_value} * and {@link unset} will fail until the next move of the cursor (calling - * {@link next} or {@link first}). + * {@link next}). */ void gee_map_iterator_unset (GeeMapIterator* self) { g_return_if_fail (self != NULL); @@ -136,10 +145,205 @@ void gee_map_iterator_unset (GeeMapIterator* self) { } +/** + * Standard aggragation function. + * + * It takes a function, seed and first element, returns the new seed and + * progress to next element when the operation repeats. + * + * Operation moves the iterator to last element in iteration. If iterator + * points at some element it will be included in iteration. + */ +static gpointer gee_map_iterator_real_fold (GeeMapIterator* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldMapFunc f, void* f_target, gpointer seed) { + gpointer result = NULL; + gboolean _tmp0_; + gboolean _tmp1_; + gpointer _tmp17_; + _tmp0_ = gee_map_iterator_get_valid (self); + _tmp1_ = _tmp0_; + if (_tmp1_) { + GeeFoldMapFunc _tmp2_; + void* _tmp2__target; + gpointer _tmp3_ = NULL; + gpointer _tmp4_; + gpointer _tmp5_ = NULL; + gpointer _tmp6_; + gpointer _tmp7_; + gpointer _tmp8_ = NULL; + _tmp2_ = f; + _tmp2__target = f_target; + _tmp3_ = gee_map_iterator_get_key (self); + _tmp4_ = _tmp3_; + _tmp5_ = gee_map_iterator_get_value (self); + _tmp6_ = _tmp5_; + _tmp7_ = seed; + seed = NULL; + _tmp8_ = _tmp2_ (_tmp4_, _tmp6_, _tmp7_, _tmp2__target); + _a_destroy_func0 (seed); + seed = _tmp8_; + ((_tmp6_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) == NULL)) ? NULL : (_tmp6_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) (_tmp6_), NULL)); + ((_tmp4_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) == NULL)) ? NULL : (_tmp4_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) (_tmp4_), NULL)); + } + while (TRUE) { + gboolean _tmp9_ = FALSE; + GeeFoldMapFunc _tmp10_; + void* _tmp10__target; + gpointer _tmp11_ = NULL; + gpointer _tmp12_; + gpointer _tmp13_ = NULL; + gpointer _tmp14_; + gpointer _tmp15_; + gpointer _tmp16_ = NULL; + _tmp9_ = gee_map_iterator_next (self); + if (!_tmp9_) { + break; + } + _tmp10_ = f; + _tmp10__target = f_target; + _tmp11_ = gee_map_iterator_get_key (self); + _tmp12_ = _tmp11_; + _tmp13_ = gee_map_iterator_get_value (self); + _tmp14_ = _tmp13_; + _tmp15_ = seed; + seed = NULL; + _tmp16_ = _tmp10_ (_tmp12_, _tmp14_, _tmp15_, _tmp10__target); + _a_destroy_func0 (seed); + seed = _tmp16_; + ((_tmp14_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) == NULL)) ? NULL : (_tmp14_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) (_tmp14_), NULL)); + ((_tmp12_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) == NULL)) ? NULL : (_tmp12_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) (_tmp12_), NULL)); + } + _tmp17_ = seed; + seed = NULL; + result = _tmp17_; + _a_destroy_func0 (seed); + return result; +} + + +gpointer gee_map_iterator_fold (GeeMapIterator* self, GType a_type, GBoxedCopyFunc a_dup_func, GDestroyNotify a_destroy_func, GeeFoldMapFunc f, void* f_target, gpointer seed) { + g_return_val_if_fail (self != NULL, NULL); + return GEE_MAP_ITERATOR_GET_INTERFACE (self)->fold (self, a_type, a_dup_func, a_destroy_func, f, f_target, seed); +} + + +/** + * Apply function to each element returned by iterator. + * + * Operation moves the iterator to last element in iteration. If iterator + * points at some element it will be included in iteration. + */ +static gboolean gee_map_iterator_real_foreach (GeeMapIterator* self, GeeForallMapFunc f, void* f_target) { + gboolean result = FALSE; + gboolean _tmp0_; + gboolean _tmp1_; + _tmp0_ = gee_map_iterator_get_valid (self); + _tmp1_ = _tmp0_; + if (_tmp1_) { + GeeForallMapFunc _tmp2_; + void* _tmp2__target; + gpointer _tmp3_ = NULL; + gpointer _tmp4_; + gpointer _tmp5_ = NULL; + gpointer _tmp6_; + gboolean _tmp7_ = FALSE; + gboolean _tmp8_; + _tmp2_ = f; + _tmp2__target = f_target; + _tmp3_ = gee_map_iterator_get_key (self); + _tmp4_ = _tmp3_; + _tmp5_ = gee_map_iterator_get_value (self); + _tmp6_ = _tmp5_; + _tmp7_ = _tmp2_ (_tmp4_, _tmp6_, _tmp2__target); + _tmp8_ = !_tmp7_; + ((_tmp6_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) == NULL)) ? NULL : (_tmp6_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) (_tmp6_), NULL)); + ((_tmp4_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) == NULL)) ? NULL : (_tmp4_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) (_tmp4_), NULL)); + if (_tmp8_) { + result = FALSE; + return result; + } + } + while (TRUE) { + gboolean _tmp9_ = FALSE; + GeeForallMapFunc _tmp10_; + void* _tmp10__target; + gpointer _tmp11_ = NULL; + gpointer _tmp12_; + gpointer _tmp13_ = NULL; + gpointer _tmp14_; + gboolean _tmp15_ = FALSE; + gboolean _tmp16_; + _tmp9_ = gee_map_iterator_next (self); + if (!_tmp9_) { + break; + } + _tmp10_ = f; + _tmp10__target = f_target; + _tmp11_ = gee_map_iterator_get_key (self); + _tmp12_ = _tmp11_; + _tmp13_ = gee_map_iterator_get_value (self); + _tmp14_ = _tmp13_; + _tmp15_ = _tmp10_ (_tmp12_, _tmp14_, _tmp10__target); + _tmp16_ = !_tmp15_; + ((_tmp14_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) == NULL)) ? NULL : (_tmp14_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_v_destroy_func (self) (_tmp14_), NULL)); + ((_tmp12_ == NULL) || (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) == NULL)) ? NULL : (_tmp12_ = (GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_k_destroy_func (self) (_tmp12_), NULL)); + if (_tmp16_) { + result = FALSE; + return result; + } + } + result = TRUE; + return result; +} + + +gboolean gee_map_iterator_foreach (GeeMapIterator* self, GeeForallMapFunc f, void* f_target) { + g_return_val_if_fail (self != NULL, FALSE); + return GEE_MAP_ITERATOR_GET_INTERFACE (self)->foreach (self, f, f_target); +} + + +gboolean gee_map_iterator_get_valid (GeeMapIterator* self) { + g_return_val_if_fail (self != NULL, FALSE); + return GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_valid (self); +} + + +gboolean gee_map_iterator_get_mutable (GeeMapIterator* self) { + g_return_val_if_fail (self != NULL, FALSE); + return GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_mutable (self); +} + + +gboolean gee_map_iterator_get_read_only (GeeMapIterator* self) { + g_return_val_if_fail (self != NULL, FALSE); + return GEE_MAP_ITERATOR_GET_INTERFACE (self)->get_read_only (self); +} + + static void gee_map_iterator_base_init (GeeMapIteratorIface * iface) { static gboolean initialized = FALSE; if (!initialized) { initialized = TRUE; + /** + * Determines wheather the call to {@link get_key}, {@link get_value} and + * {@link set_value} is legal. It is false at the beginning and after + * {@link unset} call and true otherwise. + */ + g_object_interface_install_property (iface, g_param_spec_boolean ("valid", "valid", "valid", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE)); + /** + * Determines wheather the call to {@link set_value} is legal assuming the + * iterator is valid. The value must not change in runtime hence the user + * of iterator may cache it. + */ + g_object_interface_install_property (iface, g_param_spec_boolean ("mutable", "mutable", "mutable", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE)); + /** + * Determines wheather the call to {@link unset} is legal assuming the + * iterator is valid. The value must not change in runtime hence the user + * of iterator may cache it. + */ + g_object_interface_install_property (iface, g_param_spec_boolean ("read-only", "read-only", "read-only", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE)); + iface->fold = gee_map_iterator_real_fold; + iface->foreach = gee_map_iterator_real_foreach; } } @@ -148,12 +352,12 @@ static void gee_map_iterator_base_init (GeeMapIteratorIface * iface) { * An iterator over a map. * * Gee's iterators are "on-track" iterators. They always point to an item - * except before the first call to {@link next} or {@link first}, or, when an - * item has been removed, until the next call to {@link next} or {@link first}. + * except before the first call to {@link next}, or, when an + * item has been removed, until the next call to {@link next}. * * Please note that when the iterator is out of track, neither {@link get_key}, * {@link get_value}, {@link set_value} nor {@link unset} are defined and all - * will fail. After the next call to {@link next} or {@link first}, they will + * will fail. After the next call to {@link next}, they will * be defined again. */ GType gee_map_iterator_get_type (void) { |