+#define jmap_prevval(map, index) \
+ tcon_cast_ptr(&(map)->jmap_, ccanary, \
+ jmap_prevval_(jmap_rawi((map), *(index)), \
+ (unsigned long *)(index)))
+
+
+
+/* Debugging checks. */
+static inline void jmap_debug_add_access(const struct jmap *map,
+ unsigned long index,
+ unsigned long *val,
+ const char *funcname)
+{
+#ifdef CCAN_JMAP_DEBUG
+ if (!map->acc_value) {
+ ((struct jmap *)map)->acc_value = val;
+ ((struct jmap *)map)->acc_index = index;
+ ((struct jmap *)map)->funcname = funcname;
+ }
+#endif
+ if (val)
+ assert(++((struct jmap *)map)->num_accesses);
+}
+
+static inline void jmap_debug_del_access(struct jmap *map, unsigned long **val)
+{
+ assert(--map->num_accesses >= 0);
+#ifdef CCAN_JMAP_DEBUG
+ if (map->acc_value == *val)
+ map->acc_value = NULL;
+#endif
+ /* Set it to some invalid value. Not NULL, they might rely on that! */
+ assert(memset(val, 0x42, sizeof(void *)));
+}
+
+static inline void jmap_debug_access(struct jmap *map)
+{
+#ifdef CCAN_JMAP_DEBUG
+ if (map->num_accesses && map->acc_value)
+ fprintf(stderr,
+ "jmap: still got index %lu, val %lu (%p) from %s\n",
+ map->acc_index, *map->acc_value, map->acc_value,
+ map->funcname);
+#endif
+ assert(!map->num_accesses);
+}
+
+/* Private functions */
+struct jmap *jmap_new_(size_t size);
+void jmap_free_(const struct jmap *map);
+const char *COLD jmap_error_str_(struct jmap *map);
+static inline const char *jmap_error_(struct jmap *map)
+{
+ if (JU_ERRNO(&map->err) <= JU_ERRNO_NFMAX)
+ return NULL;
+ return jmap_error_str_(map);
+}
+static inline bool jmap_add_(struct jmap *map,
+ unsigned long index, unsigned long value)
+{
+ unsigned long *val;
+ jmap_debug_access(map);
+ val = (unsigned long *)JudyLIns(&map->judy, index, &map->err);
+ if (val == PJERR)
+ return false;
+ *val = value;
+ return true;
+}
+static inline bool jmap_set_(const struct jmap *map,
+ unsigned long index, unsigned long value)
+{
+ unsigned long *val;
+ val = (unsigned long *)JudyLGet(map->judy, index,
+ (JError_t *)&map->err);
+ if (val && val != PJERR) {
+ *val = value;
+ return true;
+ }
+ return false;
+}
+static inline bool jmap_del_(struct jmap *map, unsigned long index)
+{
+ jmap_debug_access(map);
+ return JudyLDel(&map->judy, index, &map->err) == 1;
+}
+static inline bool jmap_test_(const struct jmap *map, unsigned long index)
+{
+ return JudyLGet(map->judy, index, (JError_t *)&map->err) != NULL;
+}
+static inline unsigned long jmap_get_(const struct jmap *map,
+ unsigned long index)
+{
+ unsigned long *val;
+ val = (unsigned long *)JudyLGet(map->judy, index,
+ (JError_t *)&map->err);
+ if (!val || val == PJERR)
+ return 0;
+ return *val;
+}
+static inline unsigned long jmap_popcount_(const struct jmap *map,
+ unsigned long start,
+ unsigned long end_incl)
+{
+ return JudyLCount(map->judy, start, end_incl, (JError_t *)&map->err);
+}
+static inline unsigned long jmap_nth_(const struct jmap *map,
+ unsigned long n, unsigned long invalid)
+{
+ unsigned long index;
+ if (!JudyLByCount(map->judy, n+1, &index, (JError_t *)&map->err))
+ index = invalid;
+ return index;
+}
+static inline unsigned long jmap_first_(const struct jmap *map)
+{
+ unsigned long index = 0;
+ if (!JudyLFirst(map->judy, &index, (JError_t *)&map->err))
+ index = 0;
+ else
+ assert(index != 0);
+ return index;
+}
+static inline unsigned long jmap_next_(const struct jmap *map,
+ unsigned long prev)
+{
+ if (!JudyLNext(map->judy, &prev, (JError_t *)&map->err))
+ prev = 0;
+ else
+ assert(prev != 0);
+ return prev;
+}
+static inline unsigned long jmap_last_(const struct jmap *map)
+{
+ unsigned long index = -1;
+ if (!JudyLLast(map->judy, &index, (JError_t *)&map->err))
+ index = 0;
+ else
+ assert(index != 0);
+ return index;
+}
+static inline unsigned long jmap_prev_(const struct jmap *map,
+ unsigned long prev)
+{
+ if (!JudyLPrev(map->judy, &prev, (JError_t *)&map->err))
+ prev = 0;
+ else
+ assert(prev != 0);
+ return prev;
+}
+static inline void *jmap_getval_(struct jmap *map, unsigned long index)
+{
+ unsigned long *val;
+ val = (unsigned long *)JudyLGet(map->judy, index,
+ (JError_t *)&map->err);
+ jmap_debug_add_access(map, index, val, "jmap_getval");
+ return val;
+}
+static inline void jmap_putval_(struct jmap *map, void *p)
+{
+ jmap_debug_del_access(map, p);
+}
+static inline unsigned long *jmap_nthval_(const struct jmap *map, unsigned long n,
+ unsigned long *index)
+{
+ unsigned long *val;
+ val = (unsigned long *)JudyLByCount(map->judy, n+1, index,
+ (JError_t *)&map->err);
+ jmap_debug_add_access(map, *index, val, "jmap_nthval");
+ return val;
+}
+static inline unsigned long *jmap_firstval_(const struct jmap *map,
+ unsigned long *index)
+{
+ unsigned long *val;
+ *index = 0;
+ val = (unsigned long *)JudyLFirst(map->judy, index,
+ (JError_t *)&map->err);
+ jmap_debug_add_access(map, *index, val, "jmap_firstval");
+ return val;
+}
+static inline unsigned long *jmap_nextval_(const struct jmap *map,
+ unsigned long *index)
+{
+ unsigned long *val;
+ val = (unsigned long *)JudyLNext(map->judy, index,
+ (JError_t *)&map->err);
+ jmap_debug_add_access(map, *index, val, "jmap_nextval");
+ return val;
+}
+static inline unsigned long *jmap_lastval_(const struct jmap *map,
+ unsigned long *index)
+{
+ unsigned long *val;
+ *index = -1;
+ val = (unsigned long *)JudyLLast(map->judy, index,
+ (JError_t *)&map->err);
+ jmap_debug_add_access(map, *index, val, "jmap_lastval");
+ return val;
+}
+static inline unsigned long *jmap_prevval_(const struct jmap *map,
+ unsigned long *index)