#ifndef UCX_MAP_H
#define UCX_MAP_H
#include "common.h"
#include "collection.h"
#include "string.h"
#include "hash_key.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cx_map_s CxMap;
typedef struct cx_map_entry_s CxMapEntry;
typedef struct cx_map_class_s cx_map_class;
struct cx_map_s {
CX_COLLECTION_BASE;
cx_map_class *cl;
};
enum cx_map_iterator_type {
CX_MAP_ITERATOR_PAIRS,
CX_MAP_ITERATOR_KEYS,
CX_MAP_ITERATOR_VALUES
};
struct cx_map_class_s {
__attribute__((__nonnull__))
void (*destructor)(
struct cx_map_s *map);
__attribute__((__nonnull__))
void (*clear)(
struct cx_map_s *map);
__attribute__((__nonnull__))
int (*put)(
CxMap *map,
CxHashKey key,
void *value
);
__attribute__((__nonnull__, __warn_unused_result__))
void *(*get)(
const CxMap *map,
CxHashKey key
);
__attribute__((__nonnull__))
void *(*remove)(
CxMap *map,
CxHashKey key,
bool destroy
);
__attribute__((__nonnull__, __warn_unused_result__))
CxIterator (*iterator)(
const CxMap *map,
enum cx_map_iterator_type type);
};
struct cx_map_entry_s {
const CxHashKey *key;
void *value;
};
extern CxMap *
const cxEmptyMap;
__attribute__((__nonnull__))
static inline
void cxMapStoreObjects(CxMap *map) {
map->collection.store_pointer = false;
}
__attribute__((__nonnull__))
static inline
void cxMapStorePointers(CxMap *map) {
map->collection.store_pointer = true;
map->collection.elem_size =
sizeof(
void *);
}
__attribute__((__nonnull__))
static inline bool cxMapIsStoringPointers(
const CxMap *map) {
return map->collection.store_pointer;
}
__attribute__((__nonnull__))
static inline
void cxMapDestroy(CxMap *map) {
map->cl->destructor(map);
}
__attribute__((__nonnull__))
static inline
void cxMapClear(CxMap *map) {
map->cl->clear(map);
}
__attribute__((__nonnull__))
static inline
size_t cxMapSize(
const CxMap *map) {
return map->collection.size;
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline CxIterator cxMapIteratorValues(
const CxMap *map) {
return map->cl->iterator(map,
CX_MAP_ITERATOR_VALUES);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline CxIterator cxMapIteratorKeys(
const CxMap *map) {
return map->cl->iterator(map,
CX_MAP_ITERATOR_KEYS);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline CxIterator cxMapIterator(
const CxMap *map) {
return map->cl->iterator(map,
CX_MAP_ITERATOR_PAIRS);
}
__attribute__((__nonnull__, __warn_unused_result__))
CxIterator cxMapMutIteratorValues(CxMap *map);
__attribute__((__nonnull__, __warn_unused_result__))
CxIterator cxMapMutIteratorKeys(CxMap *map);
__attribute__((__nonnull__, __warn_unused_result__))
CxIterator cxMapMutIterator(CxMap *map);
#ifdef __cplusplus
}
__attribute__((__nonnull__))
static inline
int cxMapPut(
CxMap *map,
CxHashKey
const &key,
void *value
) {
return map->cl->put(map, key, value);
}
__attribute__((__nonnull__))
static inline
int cxMapPut(
CxMap *map,
cxstring
const &key,
void *value
) {
return map->cl->put(map, cx_hash_key_cxstr(key), value);
}
__attribute__((__nonnull__))
static inline
int cxMapPut(
CxMap *map,
cxmutstr
const &key,
void *value
) {
return map->cl->put(map, cx_hash_key_cxstr(key), value);
}
__attribute__((__nonnull__))
static inline
int cxMapPut(
CxMap *map,
const char *key,
void *value
) {
return map->cl->put(map, cx_hash_key_str(key), value);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cxMapGet(
const CxMap *map,
CxHashKey
const &key
) {
return map->cl->get(map, key);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cxMapGet(
const CxMap *map,
cxstring
const &key
) {
return map->cl->get(map, cx_hash_key_cxstr(key));
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cxMapGet(
const CxMap *map,
cxmutstr
const &key
) {
return map->cl->get(map, cx_hash_key_cxstr(key));
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cxMapGet(
const CxMap *map,
const char *key
) {
return map->cl->get(map, cx_hash_key_str(key));
}
__attribute__((__nonnull__))
static inline
void cxMapRemove(
CxMap *map,
CxHashKey
const &key
) {
(
void) map->cl->remove(map, key, true);
}
__attribute__((__nonnull__))
static inline
void cxMapRemove(
CxMap *map,
cxstring
const &key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
}
__attribute__((__nonnull__))
static inline
void cxMapRemove(
CxMap *map,
cxmutstr
const &key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
}
__attribute__((__nonnull__))
static inline
void cxMapRemove(
CxMap *map,
const char *key
) {
(
void) map->cl->remove(map, cx_hash_key_str(key), true);
}
__attribute__((__nonnull__))
static inline
void cxMapDetach(
CxMap *map,
CxHashKey
const &key
) {
(
void) map->cl->remove(map, key, false);
}
__attribute__((__nonnull__))
static inline
void cxMapDetach(
CxMap *map,
cxstring
const &key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
}
__attribute__((__nonnull__))
static inline
void cxMapDetach(
CxMap *map,
cxmutstr
const &key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
}
__attribute__((__nonnull__))
static inline
void cxMapDetach(
CxMap *map,
const char *key
) {
(
void) map->cl->remove(map, cx_hash_key_str(key), false);
}
#else
__attribute__((__nonnull__))
static inline
int cx_map_put(
CxMap *map,
CxHashKey key,
void *value
) {
return map->cl->put(map, key, value);
}
__attribute__((__nonnull__))
static inline
int cx_map_put_cxstr(
CxMap *map,
cxstring key,
void *value
) {
return map->cl->put(map, cx_hash_key_cxstr(key), value);
}
__attribute__((__nonnull__))
static inline
int cx_map_put_mustr(
CxMap *map,
cxmutstr key,
void *value
) {
return map->cl->put(map, cx_hash_key_cxstr(key), value);
}
__attribute__((__nonnull__))
static inline
int cx_map_put_str(
CxMap *map,
const char *key,
void *value
) {
return map->cl->put(map, cx_hash_key_str(key), value);
}
#define cxMapPut(map, key, value) _Generic((key), \
CxHashKey: cx_map_put, \
cxstring: cx_map_put_cxstr, \
cxmutstr: cx_map_put_mustr, \
char*: cx_map_put_str, \
const char*: cx_map_put_str) \
(map, key, value)
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_get(
const CxMap *map,
CxHashKey key
) {
return map->cl->get(map, key);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_get_cxstr(
const CxMap *map,
cxstring key
) {
return map->cl->get(map, cx_hash_key_cxstr(key));
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_get_mustr(
const CxMap *map,
cxmutstr key
) {
return map->cl->get(map, cx_hash_key_cxstr(key));
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_get_str(
const CxMap *map,
const char *key
) {
return map->cl->get(map, cx_hash_key_str(key));
}
#define cxMapGet(map, key) _Generic((key), \
CxHashKey: cx_map_get, \
cxstring: cx_map_get_cxstr, \
cxmutstr: cx_map_get_mustr, \
char*: cx_map_get_str, \
const char*: cx_map_get_str) \
(map, key)
__attribute__((__nonnull__))
static inline
void cx_map_remove(
CxMap *map,
CxHashKey key
) {
(
void) map->cl->remove(map, key, true);
}
__attribute__((__nonnull__))
static inline
void cx_map_remove_cxstr(
CxMap *map,
cxstring key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
}
__attribute__((__nonnull__))
static inline
void cx_map_remove_mustr(
CxMap *map,
cxmutstr key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
}
__attribute__((__nonnull__))
static inline
void cx_map_remove_str(
CxMap *map,
const char *key
) {
(
void) map->cl->remove(map, cx_hash_key_str(key), true);
}
#define cxMapRemove(map, key) _Generic((key), \
CxHashKey: cx_map_remove, \
cxstring: cx_map_remove_cxstr, \
cxmutstr: cx_map_remove_mustr, \
char*: cx_map_remove_str, \
const char*: cx_map_remove_str) \
(map, key)
__attribute__((__nonnull__))
static inline
void cx_map_detach(
CxMap *map,
CxHashKey key
) {
(
void) map->cl->remove(map, key, false);
}
__attribute__((__nonnull__))
static inline
void cx_map_detach_cxstr(
CxMap *map,
cxstring key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
}
__attribute__((__nonnull__))
static inline
void cx_map_detach_mustr(
CxMap *map,
cxmutstr key
) {
(
void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
}
__attribute__((__nonnull__))
static inline
void cx_map_detach_str(
CxMap *map,
const char *key
) {
(
void) map->cl->remove(map, cx_hash_key_str(key), false);
}
#define cxMapDetach(map, key) _Generic((key), \
CxHashKey: cx_map_detach, \
cxstring: cx_map_detach_cxstr, \
cxmutstr: cx_map_detach_mustr, \
char*: cx_map_detach_str, \
const char*: cx_map_detach_str) \
(map, key)
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_remove_and_get(
CxMap *map,
CxHashKey key
) {
return map->cl->remove(map, key, !map->collection.store_pointer);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_remove_and_get_cxstr(
CxMap *map,
cxstring key
) {
return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_remove_and_get_mustr(
CxMap *map,
cxmutstr key
) {
return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
}
__attribute__((__nonnull__, __warn_unused_result__))
static inline
void *cx_map_remove_and_get_str(
CxMap *map,
const char *key
) {
return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
}
#define cxMapRemoveAndGet(map, key) _Generic((key), \
CxHashKey: cx_map_remove_and_get, \
cxstring: cx_map_remove_and_get_cxstr, \
cxmutstr: cx_map_remove_and_get_mustr, \
char*: cx_map_remove_and_get_str, \
const char*: cx_map_remove_and_get_str) \
(map, key)
#endif
#endif