X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fintmap%2Fintmap.h;h=be3dbc0936b40f9133b4caad30b4a49c62c1bd42;hp=f06f02d0ee599c9045c496ba7ad979d83c8b0cf0;hb=b796c0318151ce34b56d2973f567335fbf20aae7;hpb=d9e93014a999102aa1cc9979e041cd58e6aca724;ds=sidebyside diff --git a/ccan/intmap/intmap.h b/ccan/intmap/intmap.h index f06f02d0..be3dbc09 100644 --- a/ccan/intmap/intmap.h +++ b/ccan/intmap/intmap.h @@ -11,12 +11,9 @@ /* Must be an unsigned type. */ #ifndef intmap_index_t #define intmap_index_t uint64_t +#define sintmap_index_t int64_t #endif -/* Maximum possible values of each type */ -#define UINTMAP_NONE ((intmap_index_t)-1) -#define SINTMAP_NONE (((intmap_index_t)1 << (sizeof(intmap_index_t)*8))-1) - /** * struct intmap - representation of an integer map * @@ -261,52 +258,58 @@ void *intmap_del_(struct intmap *map, intmap_index_t index); void intmap_clear_(struct intmap *map); /** - * uintmap_first - get first index in an unsigned intmap + * uintmap_first - get first value in an unsigned intmap * @umap: the typed intmap to iterate through. + * @indexp: a pointer to store the index. * - * Returns UINTMAP_NONE and sets errno to ENOENT if it's empty. - * Otherwise errno is set to 0. + * Returns NULL if the map is empty, otherwise populates *@indexp and + * returns the lowest entry. */ -#define uintmap_first(umap) \ - intmap_first_(uintmap_unwrap_(umap)) +#define uintmap_first(umap, indexp) \ + tcon_cast((umap), uintmap_canary, \ + intmap_first_(uintmap_unwrap_(umap), (indexp))) + +void *intmap_first_(const struct intmap *map, intmap_index_t *indexp); /** - * sintmap_first - get first index in a signed intmap + * sintmap_first - get first value in a signed intmap * @smap: the typed intmap to iterate through. + * @indexp: a pointer to store the index. * - * Returns SINTMAP_NONE and sets errno to ENOENT if it's - * empty. Otherwise errno is set to 0. + * Returns NULL if the map is empty, otherwise populates *@indexp and + * returns the lowest entry. */ -#define sintmap_first(smap) \ - SINTMAP_UNOFF(intmap_first_(sintmap_unwrap_(smap))) - -intmap_index_t intmap_first_(const struct intmap *map); +#define sintmap_first(smap, indexp) \ + tcon_cast((smap), sintmap_canary, \ + sintmap_first_(sintmap_unwrap_(smap), (indexp))) /** * uintmap_after - get the closest following index in an unsigned intmap * @umap: the typed intmap to iterate through. - * @i: the preceeding index (may not exist) + * @indexp: the preceeding index (may not exist) * - * Returns UINTMAP_NONE and sets errno to ENOENT if there are no - * others. Otherwise errno is set to 0. + * Returns NULL if the there is no entry > @indexp, otherwise + * populates *@indexp and returns the lowest entry > @indexp. */ -#define uintmap_after(umap, i) \ - intmap_after_(uintmap_unwrap_(umap), (i)) +#define uintmap_after(umap, indexp) \ + tcon_cast((umap), uintmap_canary, \ + intmap_after_(uintmap_unwrap_(umap), (indexp))) + +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. - * @i: the preceeding index. + * @indexp: the preceeding index (may not exist) * - * Returns SINTMAP_NONE and sets errno to ENOENT if there are no - * others. Otherwise errno is set to 0. + * Returns NULL if the there is no entry > @indexp, otherwise + * populates *@indexp and returns the lowest entry > @indexp. */ -#define sintmap_after(smap, i) \ - SINTMAP_UNOFF(intmap_after_(sintmap_unwrap_(smap), SINTMAP_OFF((i)))) - -intmap_index_t intmap_after_(const struct intmap *map, intmap_index_t i); +#define sintmap_after(smap, indexp) \ + tcon_cast((smap), sintmap_canary, \ + sintmap_after_(sintmap_unwrap_(smap), (indexp))) -/* TODO: We could implement intmap_prefix, intmap_iterate... */ +/* TODO: We could implement intmap_prefix. */ /* These make sure it really is a uintmap/sintmap */ #define uintmap_unwrap_(u) (tcon_unwrap(u) + 0*tcon_sizeof((u), uintmap_canary)) @@ -317,4 +320,23 @@ intmap_index_t intmap_after_(const struct intmap *map, intmap_index_t i); #define SINTMAP_OFF(index) ((intmap_index_t)(index) + SINTMAP_OFFSET) #define SINTMAP_UNOFF(index) ((intmap_index_t)(index) - SINTMAP_OFFSET) +/* Due to multi-evaluation, these can't be macros */ +static inline void *sintmap_first_(const struct intmap *map, + sintmap_index_t *indexp) +{ + intmap_index_t i; + void *ret = intmap_first_(map, &i); + *indexp = SINTMAP_UNOFF(i); + return ret; + +} + +static inline void *sintmap_after_(const struct intmap *map, + sintmap_index_t *indexp) +{ + intmap_index_t i = SINTMAP_OFF(*indexp); + void *ret = intmap_after_(map, &i); + *indexp = SINTMAP_UNOFF(i); + return ret; +} #endif /* CCAN_INTMAP_H */