X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fintmap%2Fintmap.h;h=834c969fa7c77e46dcc262b50b7b4c80b3c9b4d5;hb=7aac849abf06ef469c2aad9a0dd6e3bb82ef1f96;hp=be3dbc0936b40f9133b4caad30b4a49c62c1bd42;hpb=b796c0318151ce34b56d2973f567335fbf20aae7;p=ccan diff --git a/ccan/intmap/intmap.h b/ccan/intmap/intmap.h index be3dbc09..834c969f 100644 --- a/ccan/intmap/intmap.h +++ b/ccan/intmap/intmap.h @@ -286,7 +286,7 @@ void *intmap_first_(const struct intmap *map, intmap_index_t *indexp); /** * uintmap_after - get the closest following index in an unsigned intmap * @umap: the typed intmap to iterate through. - * @indexp: the preceeding index (may not exist) + * @indexp: the preceding index (may not exist) * * Returns NULL if the there is no entry > @indexp, otherwise * populates *@indexp and returns the lowest entry > @indexp. @@ -300,7 +300,7 @@ void *intmap_after_(const struct intmap *map, intmap_index_t *indexp); /** * sintmap_after - get the closest following index in a signed intmap * @smap: the typed intmap to iterate through. - * @indexp: the preceeding index (may not exist) + * @indexp: the preceding index (may not exist) * * Returns NULL if the there is no entry > @indexp, otherwise * populates *@indexp and returns the lowest entry > @indexp. @@ -309,6 +309,147 @@ void *intmap_after_(const struct intmap *map, intmap_index_t *indexp); tcon_cast((smap), sintmap_canary, \ sintmap_after_(sintmap_unwrap_(smap), (indexp))) +/** + * uintmap_before - get the closest preceding index in an unsigned intmap + * @umap: the typed intmap to iterate through. + * @indexp: the succeeding index (may not exist) + * + * Returns NULL if the there is no entry < @indexp, otherwise + * populates *@indexp and returns the highest entry < @indexp. + */ +#define uintmap_before(umap, indexp) \ + tcon_cast((umap), uintmap_canary, \ + intmap_before_(uintmap_unwrap_(umap), (indexp))) + +void *intmap_before_(const struct intmap *map, intmap_index_t *indexp); + +/** + * sintmap_before - get the closest preceding index in a signed intmap + * @smap: the typed intmap to iterate through. + * @indexp: the succeeding index (may not exist) + * + * Returns NULL if the there is no entry < @indexp, otherwise + * populates *@indexp and returns the highest entry < @indexp. + */ +#define sintmap_before(smap, indexp) \ + tcon_cast((smap), sintmap_canary, \ + sintmap_before_(sintmap_unwrap_(smap), (indexp))) + +/** + * uintmap_last - get last value in an unsigned intmap + * @umap: the typed intmap to iterate through. + * @indexp: a pointer to store the index. + * + * Returns NULL if the map is empty, otherwise populates *@indexp and + * returns the highest entry. + */ +#define uintmap_last(umap, indexp) \ + tcon_cast((umap), uintmap_canary, \ + intmap_last_(uintmap_unwrap_(umap), (indexp))) + +void *intmap_last_(const struct intmap *map, intmap_index_t *indexp); + +/** + * sintmap_last - get last value in a signed intmap + * @smap: the typed intmap to iterate through. + * @indexp: a pointer to store the index. + * + * Returns NULL if the map is empty, otherwise populates *@indexp and + * returns the highest entry. + */ +#define sintmap_last(smap, indexp) \ + tcon_cast((smap), sintmap_canary, \ + sintmap_last_(sintmap_unwrap_(smap), (indexp))) + +/** + * uintmap_iterate - ordered iteration over an unsigned intmap + * @umap: the typed intmap to iterate through. + * @handle: the function to call. + * @arg: the argument for the function (types should match). + * + * @handle's prototype should be: + * bool @handle(intmap_index_t index, type value, typeof(arg) arg) + * + * If @handle returns false, the iteration will stop and uintmap_iterate will + * return false, otherwise uintmap_iterate will return true. + * You should not alter the map within the @handle function! + * + * Example: + * typedef UINTMAP(int *) umap_intp; + * static bool dump_some(intmap_index_t index, int *value, int *num) + * { + * // Only dump out num nodes. + * if (*(num--) == 0) + * return false; + * printf("%lu=>%i\n", (unsigned long)index, *value); + * return true; + * } + * + * static void dump_map(const umap_intp *map) + * { + * int max = 100; + * uintmap_iterate(map, dump_some, &max); + * if (max < 0) + * printf("... (truncated to 100 entries)\n"); + * } + */ +#define uintmap_iterate(map, handle, arg) \ + intmap_iterate_(tcon_unwrap(map), \ + typesafe_cb_cast(bool (*)(intmap_index_t, \ + void *, void *), \ + bool (*)(intmap_index_t, \ + tcon_type((map), \ + uintmap_canary), \ + __typeof__(arg)), (handle)), \ + (arg), 0) + +/** + * sintmap_iterate - ordered iteration over a signed intmap + * @smap: the typed intmap to iterate through. + * @handle: the function to call. + * @arg: the argument for the function (types should match). + * + * @handle's prototype should be: + * bool @handle(sintmap_index_t index, type value, typeof(arg) arg) + * + * If @handle returns false, the iteration will stop and sintmap_iterate will + * return false, otherwise sintmap_iterate will return true. + * You should not alter the map within the @handle function! + * + * Example: + * typedef SINTMAP(int *) smap_intp; + * static bool dump_some(sintmap_index_t index, int *value, int *num) + * { + * // Only dump out num nodes. + * if (*(num--) == 0) + * return false; + * printf("%li=>%i\n", (long)index, *value); + * return true; + * } + * + * static void dump_map(const smap_intp *map) + * { + * int max = 100; + * sintmap_iterate(map, dump_some, &max); + * if (max < 0) + * printf("... (truncated to 100 entries)\n"); + * } + */ +#define sintmap_iterate(map, handle, arg) \ + intmap_iterate_(tcon_unwrap(map), \ + typesafe_cb_cast(bool (*)(intmap_index_t, \ + void *, void *), \ + bool (*)(sintmap_index_t, \ + tcon_type((map), \ + sintmap_canary), \ + __typeof__(arg)), (handle)), \ + (arg), SINTMAP_OFFSET) + +bool intmap_iterate_(const struct intmap *map, + bool (*handle)(intmap_index_t, void *, void *), + void *data, + intmap_index_t offset); + /* TODO: We could implement intmap_prefix. */ /* These make sure it really is a uintmap/sintmap */ @@ -339,4 +480,23 @@ static inline void *sintmap_after_(const struct intmap *map, *indexp = SINTMAP_UNOFF(i); return ret; } + +static inline void *sintmap_before_(const struct intmap *map, + sintmap_index_t *indexp) +{ + intmap_index_t i = SINTMAP_OFF(*indexp); + void *ret = intmap_before_(map, &i); + *indexp = SINTMAP_UNOFF(i); + return ret; +} + +static inline void *sintmap_last_(const struct intmap *map, + sintmap_index_t *indexp) +{ + intmap_index_t i; + void *ret = intmap_last_(map, &i); + *indexp = SINTMAP_UNOFF(i); + return ret; + +} #endif /* CCAN_INTMAP_H */