X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fintmap%2Fintmap.h;h=207b7c9d2b18f993fd3a2a7692f8146391e3f864;hb=9e92552b1b2a1b631bde1c379b9f2950725b1245;hp=07a86351597dadb6f367b570ee132eab10733d33;hpb=09bb99b92546f3e8be6bb0f9218924b8491be461;p=ccan diff --git a/ccan/intmap/intmap.h b/ccan/intmap/intmap.h index 07a86351..207b7c9d 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. @@ -335,6 +335,95 @@ void *intmap_last_(const struct intmap *map, intmap_index_t *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 */