X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/fbb6b4556c347a1dec9e462574fdc2967f494002..a07e0280b245200f483e170d446156f1dea261f3:/include/xbt/dynar.h diff --git a/include/xbt/dynar.h b/include/xbt/dynar.h index d70677816f..874eb46f5b 100644 --- a/include/xbt/dynar.h +++ b/include/xbt/dynar.h @@ -1,6 +1,6 @@ /* dynar - a generic dynamic array */ -/* Copyright (c) 2004, 2005, 2006, 2007, 2009, 2010. The SimGrid Team. +/* Copyright (c) 2004-2007, 2009-2015. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -11,7 +11,7 @@ #include /* memcpy */ -#include "xbt/misc.h" /* SG_BEGIN_DECL */ +#include "xbt/base.h" /* SG_BEGIN_DECL */ #include "xbt/function_types.h" SG_BEGIN_DECL() @@ -21,13 +21,14 @@ SG_BEGIN_DECL() * * These are the SimGrid version of the dynamically size arrays, which all C programmer recode one day or another. * - * For performance concerns, the content of DynArr must be homogeneous (in - * contrary to dictionnaries -- see the \ref XBT_dict section). You thus - * have to provide the function which will be used to free the content at + * For performance concerns, the content of DynArr must be homogeneous (in contrary to dictionnaries -- see the + * \ref XBT_dict section). You thus have to provide the function which will be used to free the content at * structure creation (of type void_f_ppvoid_t or void_f_pvoid_t). * + * If you are using C++, you might want to use `std::vector` instead. + * * \section XBT_dynar_exscal Example with scalar - * \dontinclude dynar.c + * \dontinclude dynar.cpp * * \skip Vars_decl * \skip dyn @@ -52,6 +53,9 @@ SG_BEGIN_DECL() * \skip end_of_doxygen * \until } * + * Note that if you use dynars to store pointed data, the xbt_dynar_search(), xbt_dynar_search_or_negative() and + * xbt_dynar_member() won't be for you. Instead of comparing your pointed elements, they compare the pointer to them. + * See the documentation of xbt_dynar_search() for more info. */ /** @defgroup XBT_dynar_cons Dynar constructor and destructor * @ingroup XBT_dynar @@ -61,11 +65,7 @@ SG_BEGIN_DECL() /** \brief Dynar data type (opaque type) */ typedef struct xbt_dynar_s *xbt_dynar_t; - -XBT_PUBLIC(xbt_dynar_t) xbt_dynar_new(const unsigned long elm_size, - void_f_pvoid_t const free_f); -XBT_PUBLIC(xbt_dynar_t) xbt_dynar_new_sync(const unsigned long elm_size, - void_f_pvoid_t const free_f); +XBT_PUBLIC(xbt_dynar_t) xbt_dynar_new(const unsigned long elm_size, void_f_pvoid_t const free_f); XBT_PUBLIC(void) xbt_dynar_free(xbt_dynar_t * dynar); XBT_PUBLIC(void) xbt_dynar_free_voidp(void *dynar); XBT_PUBLIC(void) xbt_dynar_free_container(xbt_dynar_t * dynar); @@ -79,32 +79,21 @@ XBT_PUBLIC(void) xbt_dynar_dump(xbt_dynar_t dynar); * @{ */ -XBT_PUBLIC(void) xbt_dynar_get_cpy(const xbt_dynar_t dynar, - const unsigned long idx, - void *const dst); -XBT_PUBLIC(void) xbt_dynar_set(xbt_dynar_t dynar, const int idx, - const void *src); -XBT_PUBLIC(void) xbt_dynar_replace(xbt_dynar_t dynar, - const unsigned long idx, - const void *object); - -XBT_PUBLIC(void) xbt_dynar_insert_at(xbt_dynar_t const dynar, - const int idx, const void *src); -XBT_PUBLIC(void) xbt_dynar_remove_at(xbt_dynar_t const dynar, - const int idx, void *const dst); -XBT_PUBLIC(void) xbt_dynar_remove_n_at(xbt_dynar_t const dynar, - const unsigned int n, const int idx); +XBT_PUBLIC(void) xbt_dynar_get_cpy(const xbt_dynar_t dynar, const unsigned long idx, void *const dst); +XBT_PUBLIC(void) xbt_dynar_set(xbt_dynar_t dynar, const int idx, const void *src); +XBT_PUBLIC(void) xbt_dynar_replace(xbt_dynar_t dynar, const unsigned long idx, const void *object); +XBT_PUBLIC(void) xbt_dynar_insert_at(xbt_dynar_t const dynar, const int idx, const void *src); +XBT_PUBLIC(void) xbt_dynar_remove_at(xbt_dynar_t const dynar, const int idx, void *const dst); +XBT_PUBLIC(void) xbt_dynar_remove_n_at(xbt_dynar_t const dynar, const unsigned int n, const int idx); XBT_PUBLIC(unsigned int) xbt_dynar_search(xbt_dynar_t const dynar, void *elem); XBT_PUBLIC(signed int) xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const elem); XBT_PUBLIC(int) xbt_dynar_member(xbt_dynar_t const dynar, void *elem); -XBT_PUBLIC(void) xbt_dynar_sort(xbt_dynar_t const dynar, - int_f_cpvoid_cpvoid_t compar_fn); -XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar, - int_f_pvoid_t color); -XBT_PUBLIC(int) xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, - int(*compar)(const void *, const void *)); +XBT_PUBLIC(void) xbt_dynar_sort(xbt_dynar_t const dynar, int_f_cpvoid_cpvoid_t compar_fn); +XBT_PUBLIC(xbt_dynar_t) xbt_dynar_sort_strings(xbt_dynar_t dynar); +XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar, int_f_pvoid_t color); +XBT_PUBLIC(int) xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, int(*compar)(const void *, const void *)); XBT_PUBLIC(void *) xbt_dynar_to_array (xbt_dynar_t dynar); /** @} */ @@ -128,11 +117,9 @@ XBT_PUBLIC(void) xbt_dynar_merge(xbt_dynar_t *d1, xbt_dynar_t *d2); XBT_PUBLIC(void) xbt_dynar_push(xbt_dynar_t const dynar, const void *src); XBT_PUBLIC(void) xbt_dynar_pop(xbt_dynar_t const dynar, void *const dst); -XBT_PUBLIC(void) xbt_dynar_unshift(xbt_dynar_t const dynar, - const void *src); +XBT_PUBLIC(void) xbt_dynar_unshift(xbt_dynar_t const dynar, const void *src); XBT_PUBLIC(void) xbt_dynar_shift(xbt_dynar_t const dynar, void *const dst); -XBT_PUBLIC(void) xbt_dynar_map(const xbt_dynar_t dynar, - void_f_pvoid_t const op); +XBT_PUBLIC(void) xbt_dynar_map(const xbt_dynar_t dynar, void_f_pvoid_t const op); /** @} */ /** @defgroup XBT_dynar_ctn Direct manipulation to the dynars content @@ -143,12 +130,9 @@ XBT_PUBLIC(void) xbt_dynar_map(const xbt_dynar_t dynar, * @{ */ -XBT_PUBLIC(void *) xbt_dynar_set_at_ptr(const xbt_dynar_t dynar, - const unsigned long idx); -XBT_PUBLIC(void *) xbt_dynar_get_ptr(const xbt_dynar_t dynar, - const unsigned long idx); -XBT_PUBLIC(void *) xbt_dynar_insert_at_ptr(xbt_dynar_t const dynar, - const int idx); +XBT_PUBLIC(void *) xbt_dynar_set_at_ptr(const xbt_dynar_t dynar, const unsigned long idx); +XBT_PUBLIC(void *) xbt_dynar_get_ptr(const xbt_dynar_t dynar, const unsigned long idx); +XBT_PUBLIC(void *) xbt_dynar_insert_at_ptr(xbt_dynar_t const dynar, const int idx); XBT_PUBLIC(void *) xbt_dynar_push_ptr(xbt_dynar_t const dynar); XBT_PUBLIC(void *) xbt_dynar_pop_ptr(xbt_dynar_t const dynar); @@ -156,9 +140,8 @@ XBT_PUBLIC(void *) xbt_dynar_pop_ptr(xbt_dynar_t const dynar); /** @defgroup XBT_dynar_speed Speed optimized access to dynars of scalars * @ingroup XBT_dynar * - * While the other functions use a memcpy to retrieve the content into the - * user provided area, those ones use a regular affectation. It only works - * for scalar values, but should be a little faster. + * While the other functions use a memcpy to retrieve the content into the user provided area, those ones use a + * regular affectation. It only works for scalar values, but should be a little faster. * * @{ */ @@ -196,31 +179,24 @@ XBT_PUBLIC(void *) xbt_dynar_pop_ptr(xbt_dynar_t const dynar); /** @defgroup XBT_dynar_cursor Cursors on dynar * @ingroup XBT_dynar * - * Cursors are used to iterate over the structure. Never add elements to the - * DynArr during the traversal. To remove elements, use the - * xbt_dynar_cursor_rm() function. + * Cursors are used to iterate over the structure. Never add elements to the DynArr during the traversal. To remove + * elements, use the xbt_dynar_cursor_rm() function. * - * Do not call these functions directly, but only the xbt_dynar_foreach macro. - * - * For synchronized dynars, the dynar will be locked during the whole - * loop and it will get unlocked automatically if you traverse all - * elements. If you want to break the loop before the end, make sure - * to call xbt_dynar_cursor_unlock() before the break; + * Do not call these function directly, but only within the xbt_dynar_foreach macro. * * @{ */ -XBT_PUBLIC(void) xbt_dynar_cursor_rm(xbt_dynar_t dynar, - unsigned int *const cursor); -XBT_PUBLIC(void) xbt_dynar_cursor_unlock(xbt_dynar_t dynar); +XBT_PUBLIC(void) xbt_dynar_cursor_rm(xbt_dynar_t dynar, unsigned int *const cursor); -/* do not use this structure internals directly, but use the public interface - * This was made public to allow: - * - the inlining of the foreach elements - * - sending such beasts over the network +/* + * \warning DO NOT USE THIS STRUCTURE DIRECTLY! Instead, use the public interface: + * This was made public to allow: + * - the inlining of the foreach elements + * - sending such beasts over the network + * + * \see xbt_dynar_length() */ - -#include "xbt/synchro_core.h" typedef struct xbt_dynar_s { unsigned long size; unsigned long used; @@ -229,19 +205,7 @@ typedef struct xbt_dynar_s { void_f_pvoid_t free_f; } s_xbt_dynar_t; -static XBT_INLINE void -_xbt_dynar_cursor_first(const xbt_dynar_t dynar _XBT_GNUC_UNUSED, - unsigned int *const cursor) -{ - /* iterating over a NULL dynar is a no-op (but we don't want to have uninitialized counters) */ - - //XBT_DEBUG("Set cursor on %p to the first position", (void *) dynar); - *cursor = 0; -} - -static XBT_INLINE int -_xbt_dynar_cursor_get(const xbt_dynar_t dynar, - unsigned int idx, void *const dst) +static inline int _xbt_dynar_cursor_get(const xbt_dynar_t dynar, unsigned int idx, void *const dst) { if (!dynar) /* iterating over a NULL dynar is a no-op */ return FALSE; @@ -252,14 +216,11 @@ _xbt_dynar_cursor_get(const xbt_dynar_t dynar, } // XBT_DEBUG("Cash out cursor on %p at %u", (void *) dynar, *idx); - memcpy(dst, ((char *) dynar->data) + idx * dynar->elmsize, - dynar->elmsize); + memcpy(dst, ((char *) dynar->data) + idx * dynar->elmsize, dynar->elmsize); return TRUE; } - - /** @brief Iterates over the whole dynar. * * @param _dynar what to iterate over @@ -267,7 +228,7 @@ _xbt_dynar_cursor_get(const xbt_dynar_t dynar, * @param _data * @hideinitializer * - * \note An example of usage: + * Here is an example of usage: * \code xbt_dynar_t dyn; unsigned int cpt; @@ -276,13 +237,27 @@ xbt_dynar_foreach (dyn,cpt,str) { printf("Seen %s\n",str); } \endcode + * + * Note that underneath, that's a simple for loop with no real black magic involved. It's perfectly safe to interrupt + * a foreach with a break or a return statement. */ #define xbt_dynar_foreach(_dynar,_cursor,_data) \ - for (_xbt_dynar_cursor_first(_dynar,&(_cursor)) ; \ - _xbt_dynar_cursor_get(_dynar,_cursor,&_data) ; \ + for ( (_cursor) = 0 ; \ + _xbt_dynar_cursor_get(_dynar,_cursor,&_data) ; \ + (_cursor)++ ) + +#ifndef __cplusplus +#define xbt_dynar_foreach_ptr(_dynar,_cursor,_ptr) \ + for ((_cursor) = 0 ; \ + (_ptr = _cursor < _dynar->used ? xbt_dynar_get_ptr(_dynar,_cursor) : NULL) ; \ (_cursor)++ ) - +#else +#define xbt_dynar_foreach_ptr(_dynar,_cursor,_ptr) \ + for ((_cursor) = 0 ; \ + (_ptr = _cursor < _dynar->used ? (decltype(_ptr)) xbt_dynar_get_ptr(_dynar,_cursor) : NULL) ; \ + (_cursor)++ ) +#endif /** @} */ - SG_END_DECL() + #endif /* _XBT_DYNAR_H */