Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-10-07 02:30:41 +0300
committerJunio C Hamano <gitster@pobox.com>2019-10-07 04:20:11 +0300
commit23dee69f53cf5024ca79e0b707dcb03c63f33bef (patch)
treee99f2fd2a4e1fe622451eeaafa8c37b40413ec10 /hashmap.h
parentc8e424c9c94d97b18cd335be17f32a8ce94a5b7f (diff)
OFFSETOF_VAR macro to simplify hashmap iterators
While we cannot rely on a `__typeof__' operator being portable to use with `offsetof'; we can calculate the pointer offset using an existing pointer and the address of a member using pointer arithmetic for compilers without `__typeof__'. This allows us to simplify usage of hashmap iterator macros by not having to specify a type when a pointer of that type is already given. In the future, list iterator macros (e.g. list_for_each_entry) may also be implemented using OFFSETOF_VAR to save hackers the trouble of using container_of/list_entry macros and without relying on non-portable `__typeof__'. v3: use `__typeof__' to avoid clang warnings Signed-off-by: Eric Wong <e@80x24.org> Reviewed-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'hashmap.h')
-rw-r--r--hashmap.h44
1 files changed, 30 insertions, 14 deletions
diff --git a/hashmap.h b/hashmap.h
index 171d6ddb76..96786c724a 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -408,16 +408,32 @@ static inline struct hashmap_entry *hashmap_iter_first(struct hashmap *map,
return hashmap_iter_next(iter);
}
-#define hashmap_iter_next_entry(iter, type, member) \
- container_of_or_null(hashmap_iter_next(iter), type, member)
-
+/*
+ * returns the first entry in @map using @iter, where the entry is of
+ * @type (e.g. "struct foo") and @member is the name of the
+ * "struct hashmap_entry" in @type
+ */
#define hashmap_iter_first_entry(map, iter, type, member) \
container_of_or_null(hashmap_iter_first(map, iter), type, member)
-#define hashmap_for_each_entry(map, iter, var, type, member) \
- for (var = hashmap_iter_first_entry(map, iter, type, member); \
+/* internal macro for hashmap_for_each_entry */
+#define hashmap_iter_next_entry_offset(iter, offset) \
+ container_of_or_null_offset(hashmap_iter_next(iter), offset)
+
+/* internal macro for hashmap_for_each_entry */
+#define hashmap_iter_first_entry_offset(map, iter, offset) \
+ container_of_or_null_offset(hashmap_iter_first(map, iter), offset)
+
+/*
+ * iterate through @map using @iter, @var is a pointer to a type
+ * containing a @member which is a "struct hashmap_entry"
+ */
+#define hashmap_for_each_entry(map, iter, var, member) \
+ for (var = hashmap_iter_first_entry_offset(map, iter, \
+ OFFSETOF_VAR(var, member)); \
var; \
- var = hashmap_iter_next_entry(iter, type, member))
+ var = hashmap_iter_next_entry_offset(iter, \
+ OFFSETOF_VAR(var, member)))
/*
* returns a @pointer of @type matching @keyvar, or NULL if nothing found.
@@ -432,22 +448,22 @@ static inline struct hashmap_entry *hashmap_iter_first(struct hashmap *map,
container_of_or_null(hashmap_get_from_hash(map, hash, keydata), \
type, member)
/*
- * returns the next equal @type pointer to @var, or NULL if not found.
- * @var is a pointer of @type
- * @member is the name of the "struct hashmap_entry" field in @type
+ * returns the next equal pointer to @var, or NULL if not found.
+ * @var is a pointer of any type containing "struct hashmap_entry"
+ * @member is the name of the "struct hashmap_entry" field
*/
-#define hashmap_get_next_entry(map, var, type, member) \
- container_of_or_null(hashmap_get_next(map, &(var)->member), \
- type, member)
+#define hashmap_get_next_entry(map, var, member) \
+ container_of_or_null_offset(hashmap_get_next(map, &(var)->member), \
+ OFFSETOF_VAR(var, member))
/*
* iterate @map starting from @var, where @var is a pointer of @type
* and @member is the name of the "struct hashmap_entry" field in @type
*/
-#define hashmap_for_each_entry_from(map, var, type, member) \
+#define hashmap_for_each_entry_from(map, var, member) \
for (; \
var; \
- var = hashmap_get_next_entry(map, var, type, member))
+ var = hashmap_get_next_entry(map, var, member))
/*
* Disable item counting and automatic rehashing when adding/removing items.