X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/7a8cd62135619ad52e05ae1c929ef07e166e4260..54037339d01e1596cf2b97ba56e142bce5bce42e:/src/xbt/dynar.c diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 0fa7f41328..d6d46117af 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -1,6 +1,6 @@ /* a generic DYNamic ARray implementation. */ -/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team. +/* Copyright (c) 2004-2013. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -34,16 +34,6 @@ static XBT_INLINE void _check_inbound_idx(xbt_dynar_t dynar, int idx) } } -static XBT_INLINE void _check_sloppy_inbound_idx(xbt_dynar_t dynar, - int idx) -{ - if (idx > dynar->used) { - THROWF(bound_error, idx, - "dynar is not that long. You asked %d, but it's only %lu long (could have been equal to it)", - (int) (idx), (unsigned long) dynar->used); - } -} - static XBT_INLINE void _check_populated_dynar(xbt_dynar_t dynar) { if (dynar->used == 0) { @@ -425,8 +415,60 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, dynar->used--; } +/** @brief Remove a slice of the dynar, sliding the rest of the values to the left + * + * This function removes an n-sized slice that starts at element idx. It is equivalent + * to xbt_dynar_remove_at with a NULL object argument if n equals to 1. + * + * Each of the removed elements is freed using the free_f function passed at dynar + * creation. + */ +void +xbt_dynar_remove_n_at(xbt_dynar_t const dynar, + const unsigned int n, const int idx) +{ + unsigned long nb_shift; + unsigned long offset; + unsigned long cur; + + if (!n) return; + + _sanity_check_dynar(dynar); + _check_inbound_idx(dynar, idx); + _check_inbound_idx(dynar, idx + n - 1); + + if (dynar->free_f) { + for (cur = idx; cur < idx + n; cur++) { + dynar->free_f(_xbt_dynar_elm(dynar, cur)); + } + } + + nb_shift = dynar->used - n - idx; + + if (nb_shift) { + offset = nb_shift * dynar->elmsize; + memmove(_xbt_dynar_elm(dynar, idx), _xbt_dynar_elm(dynar, idx + n), + offset); + } + + dynar->used -= n; +} + /** @brief Returns the position of the element in the dynar * + * Beware that if your dynar contains pointed values (such as strings) instead + * of scalar, this function compares the pointer value, not what's pointed. The only + * solution to search for a pointed value is then to write the foreach loop yourself: + * \code + * signed int position = -1; + * xbt_dynar_foreach(dynar, iter, elem) { + * if (!memcmp(elem, searched_element, sizeof(*elem))) { + * position = iter; + * break; + * } + * } + * \endcode + * * Raises not_found_error if not found. If you have less than 2 millions elements, * you probably want to use #xbt_dynar_search_or_negative() instead, so that you * don't have to TRY/CATCH on element not found. @@ -446,6 +488,10 @@ unsigned int xbt_dynar_search(xbt_dynar_t const dynar, void *const elem) /** @brief Returns the position of the element in the dynar (or -1 if not found) * + * Beware that if your dynar contains pointed values (such as + * strings) instead of scalar, this function is probably not what you + * want. Check the documentation of xbt_dynar_search() for more info. + * * Note that usually, the dynar indices are unsigned integers. If you have more * than 2 million elements in your dynar, this very function will not work (but the other will). */ @@ -461,7 +507,12 @@ signed int xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const ele return -1; } -/** @brief Returns a boolean indicating whether the element is part of the dynar */ +/** @brief Returns a boolean indicating whether the element is part of the dynar + * + * Beware that if your dynar contains pointed values (such as + * strings) instead of scalar, this function is probably not what you + * want. Check the documentation of xbt_dynar_search() for more info. + */ int xbt_dynar_member(xbt_dynar_t const dynar, void *const elem) { @@ -487,9 +538,6 @@ int xbt_dynar_member(xbt_dynar_t const dynar, void *const elem) */ XBT_INLINE void *xbt_dynar_push_ptr(xbt_dynar_t const dynar) { - /* we have to inline xbt_dynar_insert_at_ptr here to make sure that - dynar->used don't change between reading it and getting the lock - within xbt_dynar_insert_at_ptr */ return xbt_dynar_insert_at_ptr(dynar, dynar->used); } @@ -498,8 +546,7 @@ XBT_INLINE void xbt_dynar_push(xbt_dynar_t const dynar, const void *const src) { /* checks done in xbt_dynar_insert_at_ptr */ - memcpy(xbt_dynar_insert_at_ptr(dynar, dynar->used), src, - dynar->elmsize); + memcpy(xbt_dynar_insert_at_ptr(dynar, dynar->used), src, dynar->elmsize); } /** @brief Mark the last dynar's element as unused and return a pointer to it. @@ -660,7 +707,7 @@ XBT_INLINE void * xbt_dynar_to_array (xbt_dynar_t dynar) /* * Return 0 if d1 and d2 are equal and 1 if not equal */ -XBT_INLINE int xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, +int xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, int(*compar)(const void *, const void *)) { int i ;