2008-08-11 09:30:16 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2008 Cedric Bail
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef EINA_ITERATOR_H__
|
|
|
|
#define EINA_ITERATOR_H__
|
|
|
|
|
2008-12-08 02:51:51 -08:00
|
|
|
#include "eina_config.h"
|
|
|
|
|
2008-08-11 09:30:16 -07:00
|
|
|
#include "eina_types.h"
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
#include "eina_magic.h"
|
2008-08-11 09:30:16 -07:00
|
|
|
|
2009-06-22 13:03:58 -07:00
|
|
|
/**
|
|
|
|
* @addtogroup Eina_Content_Access_Group Content Access
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2008-09-06 22:44:00 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Eina_Iterator_Group Iterator Functions
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef Eina_Iterator
|
|
|
|
* Type for iterators.
|
|
|
|
*/
|
2008-08-11 09:30:16 -07:00
|
|
|
typedef struct _Eina_Iterator Eina_Iterator;
|
|
|
|
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
typedef Eina_Bool (*Eina_Iterator_Next_Callback)(Eina_Iterator *it, void **data);
|
|
|
|
typedef void *(*Eina_Iterator_Get_Container_Callback)(Eina_Iterator *it);
|
|
|
|
typedef void (*Eina_Iterator_Free_Callback)(Eina_Iterator *it);
|
2010-08-11 07:32:30 -07:00
|
|
|
typedef Eina_Bool (*Eina_Iterator_Lock_Callback)(Eina_Iterator *it);
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
|
|
|
|
struct _Eina_Iterator
|
|
|
|
{
|
2010-08-19 05:02:28 -07:00
|
|
|
#define EINA_ITERATOR_VERSION 1
|
|
|
|
int version;
|
|
|
|
|
2010-08-12 23:36:33 -07:00
|
|
|
Eina_Iterator_Next_Callback next EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
|
|
|
|
Eina_Iterator_Get_Container_Callback get_container EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
2010-07-27 19:37:05 -07:00
|
|
|
Eina_Iterator_Free_Callback free EINA_ARG_NONNULL(1);
|
2008-12-05 22:53:14 -08:00
|
|
|
|
2010-08-11 07:32:30 -07:00
|
|
|
Eina_Iterator_Lock_Callback lock EINA_WARN_UNUSED_RESULT;
|
|
|
|
Eina_Iterator_Lock_Callback unlock EINA_WARN_UNUSED_RESULT;
|
|
|
|
|
2008-12-05 22:53:14 -08:00
|
|
|
#define EINA_MAGIC_ITERATOR 0x98761233
|
* eina/src/include/eina_array.h,
* eina/src/include/eina_f16p16.h,
* eina/src/include/eina_accessor.h,
* eina/src/include/eina_list.h,
* eina/src/include/eina_iterator.h,
* eina/src/lib/eina_rectangle.c,
* eina/src/lib/eina_list.c,
* eina/src/lib/eina_array.c,
* eina/src/lib/eina_hash.c,
* eina/src/lib/eina_module.c,
* eina/src/lib/eina_stringshare.c,
* eina/src/lib/eina_benchmark.c: Fix for windows compilation.
SVN revision: 38663
2009-01-20 07:56:48 -08:00
|
|
|
EINA_MAGIC
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define FUNC_ITERATOR_NEXT(Function) ((Eina_Iterator_Next_Callback)Function)
|
2010-07-27 19:37:05 -07:00
|
|
|
#define FUNC_ITERATOR_GET_CONTAINER(Function) (( \
|
|
|
|
Eina_Iterator_Get_Container_Callback) \
|
|
|
|
Function)
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
#define FUNC_ITERATOR_FREE(Function) ((Eina_Iterator_Free_Callback)Function)
|
2010-08-11 07:32:30 -07:00
|
|
|
#define FUNC_ITERATOR_LOCK(Function) ((Eina_Iterator_Lock_Callback)Function)
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
|
2010-08-12 23:36:33 -07:00
|
|
|
EAPI void eina_iterator_free (Eina_Iterator *iterator) EINA_ARG_NONNULL(1);
|
2008-08-11 09:30:16 -07:00
|
|
|
|
2010-08-12 23:36:33 -07:00
|
|
|
EAPI void * eina_iterator_container_get (Eina_Iterator *iterator) EINA_ARG_NONNULL(1) EINA_PURE;
|
2010-07-27 19:37:05 -07:00
|
|
|
EAPI Eina_Bool eina_iterator_next (Eina_Iterator *iterator,
|
2010-08-12 23:36:33 -07:00
|
|
|
void **data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
|
2008-08-11 09:30:16 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
EAPI void eina_iterator_foreach (Eina_Iterator *iterator,
|
2010-08-11 07:32:30 -07:00
|
|
|
Eina_Each_Cb callback,
|
2010-08-12 23:36:33 -07:00
|
|
|
const void *fdata) EINA_ARG_NONNULL(1, 2);
|
2008-08-11 09:30:16 -07:00
|
|
|
|
2010-08-11 07:32:30 -07:00
|
|
|
EAPI Eina_Bool eina_iterator_lock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1);
|
|
|
|
EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1);
|
|
|
|
|
2009-02-27 08:32:22 -08:00
|
|
|
/**
|
|
|
|
* @def EINA_ITERATOR_FOREACH
|
|
|
|
* @brief Macro to iterate over all elements easily.
|
|
|
|
*
|
2009-12-27 00:45:30 -08:00
|
|
|
* @param itr The iterator to use.
|
2009-02-27 08:32:22 -08:00
|
|
|
* @param data Where to store * data, must be a pointer support getting
|
|
|
|
* its address since * eina_iterator_next() requires a pointer
|
|
|
|
* to pointer!
|
|
|
|
*
|
|
|
|
* This macro is a convenient way to use iterators, very similar to
|
|
|
|
* EINA_LIST_FOREACH().
|
|
|
|
*
|
|
|
|
* This macro can be used for freeing the data of a list, like in the
|
|
|
|
* following example. It has the same goal as the one documented in
|
|
|
|
* EINA_LIST_FOREACH(), but using iterators:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* Eina_List *list;
|
|
|
|
* Eina_Iterator *itr;
|
|
|
|
* char *data;
|
|
|
|
*
|
|
|
|
* // list is already filled,
|
|
|
|
* // its elements are just duplicated strings
|
|
|
|
*
|
|
|
|
* itr = eina_list_iterator_new(list);
|
|
|
|
* EINA_ITERATOR_FOREACH(itr, data)
|
|
|
|
* free(data);
|
|
|
|
* eina_iterator_free(itr);
|
|
|
|
* eina_list_free(list);
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* @note this example is not optimal algorithm to release a list since
|
|
|
|
* it will walk the list twice, but it serves as an example. For
|
|
|
|
* optimized version use EINA_LIST_FREE()
|
|
|
|
*
|
|
|
|
* @warning unless explicitly stated in functions returning iterators,
|
|
|
|
* do not modify the iterated object while you walk it, in this
|
|
|
|
* example using lists, do not remove list nodes or you might
|
|
|
|
* crash! This is not a limitiation of iterators themselves,
|
|
|
|
* rather in the iterators implementations to keep them as simple
|
|
|
|
* and fast as possible.
|
|
|
|
*/
|
2010-07-27 19:37:05 -07:00
|
|
|
#define EINA_ITERATOR_FOREACH(itr, \
|
|
|
|
data) while (eina_iterator_next((itr), \
|
|
|
|
(void **)&(data)))
|
2009-02-27 08:32:22 -08:00
|
|
|
|
2009-06-22 13:03:58 -07:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2008-09-06 22:44:00 -07:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2008-08-11 09:30:16 -07:00
|
|
|
#endif
|