src/cx/map.h

Fri, 21 Apr 2023 20:50:19 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 21 Apr 2023 20:50:19 +0200
changeset 694
ac827d873c17
parent 692
6ac92936cd44
child 706
8c6edaccaef1
permissions
-rw-r--r--

fix missing controlling-expression for char const*

universe@549 1 /*
universe@549 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@549 3 *
universe@549 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@549 5 *
universe@549 6 * Redistribution and use in source and binary forms, with or without
universe@549 7 * modification, are permitted provided that the following conditions are met:
universe@549 8 *
universe@549 9 * 1. Redistributions of source code must retain the above copyright
universe@549 10 * notice, this list of conditions and the following disclaimer.
universe@549 11 *
universe@549 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@549 13 * notice, this list of conditions and the following disclaimer in the
universe@549 14 * documentation and/or other materials provided with the distribution.
universe@549 15 *
universe@549 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@549 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@549 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@549 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@549 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@549 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@549 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@549 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@549 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@549 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@549 26 * POSSIBILITY OF SUCH DAMAGE.
universe@549 27 */
universe@549 28 /**
universe@549 29 * \file map.h
universe@549 30 * \brief Interface for map implementations.
universe@549 31 * \author Mike Becker
universe@549 32 * \author Olaf Wintermann
universe@549 33 * \version 3.0
universe@549 34 * \copyright 2-Clause BSD License
universe@549 35 */
universe@549 36
universe@549 37 #ifndef UCX_MAP_H
universe@549 38 #define UCX_MAP_H
universe@549 39
universe@681 40 #include "common.h"
universe@677 41 #include "collection.h"
universe@691 42 #include "string.h"
universe@563 43 #include "hash_key.h"
universe@549 44
universe@549 45 #ifdef __cplusplus
universe@549 46 extern "C" {
universe@549 47 #endif
universe@549 48
universe@549 49 /** Type for the UCX map. */
universe@549 50 typedef struct cx_map_s CxMap;
universe@549 51
universe@549 52 /** Type for a map entry. */
universe@549 53 typedef struct cx_map_entry_s CxMapEntry;
universe@549 54
universe@549 55 /** Type for map class definitions. */
universe@549 56 typedef struct cx_map_class_s cx_map_class;
universe@549 57
universe@549 58 /** Structure for the UCX map. */
universe@549 59 struct cx_map_s {
universe@685 60 CX_COLLECTION_MEMBERS
universe@549 61 /** The map class definition. */
universe@549 62 cx_map_class *cl;
universe@549 63 };
universe@549 64
universe@549 65 /**
universe@549 66 * The class definition for arbitrary maps.
universe@549 67 */
universe@549 68 struct cx_map_class_s {
universe@549 69 /**
universe@549 70 * Deallocates the entire memory.
universe@549 71 */
universe@549 72 __attribute__((__nonnull__))
universe@549 73 void (*destructor)(struct cx_map_s *map);
universe@549 74
universe@549 75 /**
universe@549 76 * Removes all elements.
universe@549 77 */
universe@549 78 __attribute__((__nonnull__))
universe@549 79 void (*clear)(struct cx_map_s *map);
universe@549 80
universe@549 81 /**
universe@549 82 * Add or overwrite an element.
universe@549 83 */
universe@549 84 __attribute__((__nonnull__))
universe@549 85 int (*put)(
universe@549 86 CxMap *map,
universe@563 87 CxHashKey key,
universe@550 88 void *value
universe@549 89 );
universe@549 90
universe@549 91 /**
universe@549 92 * Returns an element.
universe@549 93 */
universe@549 94 __attribute__((__nonnull__, __warn_unused_result__))
universe@549 95 void *(*get)(
universe@549 96 CxMap const *map,
universe@563 97 CxHashKey key
universe@549 98 );
universe@549 99
universe@549 100 /**
universe@549 101 * Removes an element.
universe@549 102 */
universe@659 103 __attribute__((__nonnull__))
universe@549 104 void *(*remove)(
universe@550 105 CxMap *map,
universe@686 106 CxHashKey key,
universe@686 107 bool destroy
universe@549 108 );
universe@549 109
universe@549 110 /**
universe@549 111 * Iterator over the key/value pairs.
universe@549 112 */
universe@549 113 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 114 CxIterator (*iterator)(CxMap const *map);
universe@549 115
universe@549 116 /**
universe@549 117 * Iterator over the keys.
universe@549 118 */
universe@549 119 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 120 CxIterator (*iterator_keys)(CxMap const *map);
universe@549 121
universe@549 122 /**
universe@549 123 * Iterator over the values.
universe@549 124 */
universe@549 125 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 126 CxIterator (*iterator_values)(CxMap const *map);
universe@630 127
universe@630 128 /**
universe@630 129 * Mutating iterator over the key/value pairs.
universe@630 130 */
universe@630 131 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 132 CxMutIterator (*mut_iterator)(CxMap *map);
universe@630 133
universe@630 134 /**
universe@630 135 * Mutating iterator over the keys.
universe@630 136 */
universe@630 137 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 138 CxMutIterator (*mut_iterator_keys)(CxMap *map);
universe@630 139
universe@630 140 /**
universe@630 141 * Mutating iterator over the values.
universe@630 142 */
universe@630 143 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 144 CxMutIterator (*mut_iterator_values)(CxMap *map);
universe@549 145 };
universe@549 146
universe@549 147 /**
universe@549 148 * A map entry.
universe@549 149 */
universe@549 150 struct cx_map_entry_s {
universe@549 151 /**
universe@551 152 * A pointer to the key.
universe@549 153 */
universe@563 154 CxHashKey const *key;
universe@549 155 /**
universe@551 156 * A pointer to the value.
universe@549 157 */
universe@551 158 void *value;
universe@549 159 };
universe@549 160
universe@658 161 /**
universe@658 162 * Advises the map to store copies of the objects (default mode of operation).
universe@658 163 *
universe@658 164 * Retrieving objects from this map will yield pointers to the copies stored
universe@658 165 * within this list.
universe@658 166 *
universe@658 167 * @param map the map
universe@658 168 * @see cxMapStorePointers()
universe@658 169 */
universe@658 170 __attribute__((__nonnull__))
universe@658 171 static inline void cxMapStoreObjects(CxMap *map) {
universe@685 172 map->store_pointer = false;
universe@658 173 }
universe@658 174
universe@658 175 /**
universe@658 176 * Advises the map to only store pointers to the objects.
universe@658 177 *
universe@658 178 * Retrieving objects from this list will yield the original pointers stored.
universe@658 179 *
universe@658 180 * @note This function forcibly sets the element size to the size of a pointer.
universe@658 181 * Invoking this function on a non-empty map that already stores copies of
universe@658 182 * objects is undefined.
universe@658 183 *
universe@658 184 * @param map the map
universe@658 185 * @see cxMapStoreObjects()
universe@658 186 */
universe@658 187 __attribute__((__nonnull__))
universe@658 188 static inline void cxMapStorePointers(CxMap *map) {
universe@685 189 map->store_pointer = true;
universe@677 190 map->item_size = sizeof(void *);
universe@658 191 }
universe@658 192
universe@549 193
universe@549 194 /**
universe@549 195 * Deallocates the memory of the specified map.
universe@549 196 *
universe@549 197 * @param map the map to be destroyed
universe@549 198 */
universe@549 199 __attribute__((__nonnull__))
universe@549 200 static inline void cxMapDestroy(CxMap *map) {
universe@549 201 map->cl->destructor(map);
universe@549 202 }
universe@549 203
universe@549 204
universe@549 205 /**
universe@549 206 * Clears a map by removing all elements.
universe@549 207 *
universe@549 208 * @param map the map to be cleared
universe@549 209 */
universe@549 210 __attribute__((__nonnull__))
universe@549 211 static inline void cxMapClear(CxMap *map) {
universe@549 212 map->cl->clear(map);
universe@549 213 }
universe@549 214
universe@549 215
universe@549 216 // TODO: set-like map operations (union, intersect, difference)
universe@549 217
universe@549 218 /**
universe@549 219 * Creates a value iterator for a map.
universe@549 220 *
universe@549 221 * \note An iterator iterates over all elements successively. Therefore the order
universe@549 222 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@549 223 *
universe@549 224 * @param map the map to create the iterator for
universe@549 225 * @return an iterator for the currently stored values
universe@549 226 */
universe@549 227 __attribute__((__nonnull__, __warn_unused_result__))
universe@551 228 static inline CxIterator cxMapIteratorValues(CxMap *map) {
universe@549 229 return map->cl->iterator_values(map);
universe@549 230 }
universe@549 231
universe@549 232 /**
universe@549 233 * Creates a key iterator for a map.
universe@549 234 *
universe@564 235 * The elements of the iterator are keys of type CxHashKey.
universe@555 236 *
universe@549 237 * \note An iterator iterates over all elements successively. Therefore the order
universe@549 238 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@549 239 *
universe@549 240 * @param map the map to create the iterator for
universe@549 241 * @return an iterator for the currently stored keys
universe@549 242 */
universe@549 243 __attribute__((__nonnull__, __warn_unused_result__))
universe@551 244 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
universe@549 245 return map->cl->iterator_keys(map);
universe@549 246 }
universe@549 247
universe@549 248 /**
universe@549 249 * Creates an iterator for a map.
universe@549 250 *
universe@555 251 * The elements of the iterator are key/value pairs of type CxMapEntry.
universe@549 252 *
universe@549 253 * \note An iterator iterates over all elements successively. Therefore the order
universe@549 254 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@549 255 *
universe@549 256 * @param map the map to create the iterator for
universe@555 257 * @return an iterator for the currently stored entries
universe@549 258 * @see cxMapIteratorKeys()
universe@549 259 * @see cxMapIteratorValues()
universe@549 260 */
universe@549 261 __attribute__((__nonnull__, __warn_unused_result__))
universe@551 262 static inline CxIterator cxMapIterator(CxMap *map) {
universe@549 263 return map->cl->iterator(map);
universe@549 264 }
universe@549 265
universe@630 266
universe@630 267 /**
universe@630 268 * Creates a mutating iterator over the values of a map.
universe@630 269 *
universe@630 270 * \note An iterator iterates over all elements successively. Therefore the order
universe@630 271 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@630 272 *
universe@630 273 * @param map the map to create the iterator for
universe@630 274 * @return an iterator for the currently stored values
universe@630 275 */
universe@630 276 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 277 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
universe@630 278 return map->cl->mut_iterator_values(map);
universe@630 279 }
universe@630 280
universe@630 281 /**
universe@630 282 * Creates a mutating iterator over the keys of a map.
universe@630 283 *
universe@630 284 * The elements of the iterator are keys of type CxHashKey.
universe@630 285 *
universe@630 286 * \note An iterator iterates over all elements successively. Therefore the order
universe@630 287 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@630 288 *
universe@630 289 * @param map the map to create the iterator for
universe@630 290 * @return an iterator for the currently stored keys
universe@630 291 */
universe@630 292 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 293 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
universe@630 294 return map->cl->mut_iterator_keys(map);
universe@630 295 }
universe@630 296
universe@630 297 /**
universe@630 298 * Creates a mutating iterator for a map.
universe@630 299 *
universe@630 300 * The elements of the iterator are key/value pairs of type CxMapEntry.
universe@630 301 *
universe@630 302 * \note An iterator iterates over all elements successively. Therefore the order
universe@630 303 * highly depends on the map implementation and may change arbitrarily when the contents change.
universe@630 304 *
universe@630 305 * @param map the map to create the iterator for
universe@630 306 * @return an iterator for the currently stored entries
universe@630 307 * @see cxMapMutIteratorKeys()
universe@630 308 * @see cxMapMutIteratorValues()
universe@630 309 */
universe@630 310 __attribute__((__nonnull__, __warn_unused_result__))
universe@630 311 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
universe@630 312 return map->cl->mut_iterator(map);
universe@630 313 }
universe@630 314
universe@691 315 #ifdef __cplusplus
universe@691 316 } // end the extern "C" block here, because we want to start overloading
universe@691 317
universe@691 318 /**
universe@691 319 * Puts a key/value-pair into the map.
universe@691 320 *
universe@691 321 * @param map the map
universe@691 322 * @param key the key
universe@691 323 * @param value the value
universe@691 324 * @return 0 on success, non-zero value on failure
universe@691 325 */
universe@691 326 __attribute__((__nonnull__))
universe@691 327 static inline int cxMapPut(
universe@691 328 CxMap *map,
universe@691 329 CxHashKey const &key,
universe@691 330 void *value
universe@691 331 ) {
universe@691 332 return map->cl->put(map, key, value);
universe@549 333 }
universe@549 334
universe@691 335
universe@691 336 /**
universe@691 337 * Puts a key/value-pair into the map.
universe@691 338 *
universe@691 339 * @param map the map
universe@691 340 * @param key the key
universe@691 341 * @param value the value
universe@691 342 * @return 0 on success, non-zero value on failure
universe@691 343 */
universe@691 344 __attribute__((__nonnull__))
universe@691 345 static inline int cxMapPut(
universe@691 346 CxMap *map,
universe@691 347 cxstring const &key,
universe@691 348 void *value
universe@691 349 ) {
universe@691 350 return map->cl->put(map, cx_hash_key_cxstr(key), value);
universe@691 351 }
universe@691 352
universe@691 353 /**
universe@691 354 * Puts a key/value-pair into the map.
universe@691 355 *
universe@691 356 * @param map the map
universe@691 357 * @param key the key
universe@691 358 * @param value the value
universe@691 359 * @return 0 on success, non-zero value on failure
universe@691 360 */
universe@691 361 __attribute__((__nonnull__))
universe@691 362 static inline int cxMapPut(
universe@691 363 CxMap *map,
universe@692 364 cxmutstr const &key,
universe@692 365 void *value
universe@692 366 ) {
universe@692 367 return map->cl->put(map, cx_hash_key_cxstr(key), value);
universe@692 368 }
universe@692 369
universe@692 370 /**
universe@692 371 * Puts a key/value-pair into the map.
universe@692 372 *
universe@692 373 * @param map the map
universe@692 374 * @param key the key
universe@692 375 * @param value the value
universe@692 376 * @return 0 on success, non-zero value on failure
universe@692 377 */
universe@692 378 __attribute__((__nonnull__))
universe@692 379 static inline int cxMapPut(
universe@692 380 CxMap *map,
universe@691 381 char const *key,
universe@691 382 void *value
universe@691 383 ) {
universe@691 384 return map->cl->put(map, cx_hash_key_str(key), value);
universe@691 385 }
universe@691 386
universe@691 387 /**
universe@691 388 * Retrieves a value by using a key.
universe@691 389 *
universe@691 390 * @param map the map
universe@691 391 * @param key the key
universe@691 392 * @return the value
universe@691 393 */
universe@691 394 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 395 static inline void *cxMapGet(
universe@691 396 CxMap const *map,
universe@691 397 CxHashKey const &key
universe@691 398 ) {
universe@691 399 return map->cl->get(map, key);
universe@691 400 }
universe@691 401
universe@691 402 /**
universe@691 403 * Retrieves a value by using a key.
universe@691 404 *
universe@691 405 * @param map the map
universe@691 406 * @param key the key
universe@691 407 * @return the value
universe@691 408 */
universe@691 409 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 410 static inline void *cxMapGet(
universe@691 411 CxMap const *map,
universe@691 412 cxstring const &key
universe@691 413 ) {
universe@691 414 return map->cl->get(map, cx_hash_key_cxstr(key));
universe@691 415 }
universe@691 416
universe@691 417 /**
universe@691 418 * Retrieves a value by using a key.
universe@691 419 *
universe@691 420 * @param map the map
universe@691 421 * @param key the key
universe@691 422 * @return the value
universe@691 423 */
universe@691 424 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 425 static inline void *cxMapGet(
universe@691 426 CxMap const *map,
universe@692 427 cxmutstr const &key
universe@692 428 ) {
universe@692 429 return map->cl->get(map, cx_hash_key_cxstr(key));
universe@692 430 }
universe@692 431
universe@692 432 /**
universe@692 433 * Retrieves a value by using a key.
universe@692 434 *
universe@692 435 * @param map the map
universe@692 436 * @param key the key
universe@692 437 * @return the value
universe@692 438 */
universe@692 439 __attribute__((__nonnull__, __warn_unused_result__))
universe@692 440 static inline void *cxMapGet(
universe@692 441 CxMap const *map,
universe@691 442 char const *key
universe@691 443 ) {
universe@691 444 return map->cl->get(map, cx_hash_key_str(key));
universe@691 445 }
universe@691 446
universe@691 447 /**
universe@691 448 * Removes a key/value-pair from the map by using the key.
universe@691 449 *
universe@691 450 * Always invokes the destructor function, if any, on the removed element.
universe@691 451 * If this map is storing pointers and you just want to retrieve the pointer
universe@691 452 * without invoking the destructor, use cxMapRemoveAndGet().
universe@691 453 * If you just want to detach the element from the map without invoking the
universe@691 454 * destructor or returning the element, use cxMapDetach().
universe@691 455 *
universe@691 456 * @param map the map
universe@691 457 * @param key the key
universe@691 458 * @see cxMapRemoveAndGet()
universe@691 459 * @see cxMapDetach()
universe@691 460 */
universe@691 461 __attribute__((__nonnull__))
universe@691 462 static inline void cxMapRemove(
universe@691 463 CxMap *map,
universe@691 464 CxHashKey const &key
universe@691 465 ) {
universe@691 466 (void) map->cl->remove(map, key, true);
universe@691 467 }
universe@691 468
universe@691 469 /**
universe@691 470 * Removes a key/value-pair from the map by using the key.
universe@691 471 *
universe@691 472 * Always invokes the destructor function, if any, on the removed element.
universe@691 473 * If this map is storing pointers and you just want to retrieve the pointer
universe@691 474 * without invoking the destructor, use cxMapRemoveAndGet().
universe@691 475 * If you just want to detach the element from the map without invoking the
universe@691 476 * destructor or returning the element, use cxMapDetach().
universe@691 477 *
universe@691 478 * @param map the map
universe@691 479 * @param key the key
universe@691 480 * @see cxMapRemoveAndGet()
universe@691 481 * @see cxMapDetach()
universe@691 482 */
universe@691 483 __attribute__((__nonnull__))
universe@691 484 static inline void cxMapRemove(
universe@691 485 CxMap *map,
universe@691 486 cxstring const &key
universe@691 487 ) {
universe@691 488 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
universe@691 489 }
universe@691 490
universe@691 491 /**
universe@691 492 * Removes a key/value-pair from the map by using the key.
universe@691 493 *
universe@691 494 * Always invokes the destructor function, if any, on the removed element.
universe@691 495 * If this map is storing pointers and you just want to retrieve the pointer
universe@691 496 * without invoking the destructor, use cxMapRemoveAndGet().
universe@691 497 * If you just want to detach the element from the map without invoking the
universe@691 498 * destructor or returning the element, use cxMapDetach().
universe@691 499 *
universe@691 500 * @param map the map
universe@691 501 * @param key the key
universe@691 502 * @see cxMapRemoveAndGet()
universe@691 503 * @see cxMapDetach()
universe@691 504 */
universe@691 505 __attribute__((__nonnull__))
universe@691 506 static inline void cxMapRemove(
universe@691 507 CxMap *map,
universe@692 508 cxmutstr const &key
universe@692 509 ) {
universe@692 510 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
universe@692 511 }
universe@692 512
universe@692 513 /**
universe@692 514 * Removes a key/value-pair from the map by using the key.
universe@692 515 *
universe@692 516 * Always invokes the destructor function, if any, on the removed element.
universe@692 517 * If this map is storing pointers and you just want to retrieve the pointer
universe@692 518 * without invoking the destructor, use cxMapRemoveAndGet().
universe@692 519 * If you just want to detach the element from the map without invoking the
universe@692 520 * destructor or returning the element, use cxMapDetach().
universe@692 521 *
universe@692 522 * @param map the map
universe@692 523 * @param key the key
universe@692 524 * @see cxMapRemoveAndGet()
universe@692 525 * @see cxMapDetach()
universe@692 526 */
universe@692 527 __attribute__((__nonnull__))
universe@692 528 static inline void cxMapRemove(
universe@692 529 CxMap *map,
universe@691 530 char const *key
universe@691 531 ) {
universe@691 532 (void) map->cl->remove(map, cx_hash_key_str(key), true);
universe@691 533 }
universe@691 534
universe@691 535 /**
universe@691 536 * Detaches a key/value-pair from the map by using the key
universe@691 537 * without invoking the destructor.
universe@691 538 *
universe@691 539 * In general, you should only use this function if the map does not own
universe@691 540 * the data and there is a valid reference to the data somewhere else
universe@691 541 * in the program. In all other cases it is preferable to use
universe@691 542 * cxMapRemove() or cxMapRemoveAndGet().
universe@691 543 *
universe@691 544 * @param map the map
universe@691 545 * @param key the key
universe@691 546 * @see cxMapRemove()
universe@691 547 * @see cxMapRemoveAndGet()
universe@691 548 */
universe@691 549 __attribute__((__nonnull__))
universe@691 550 static inline void cxMapDetach(
universe@691 551 CxMap *map,
universe@691 552 CxHashKey const &key
universe@691 553 ) {
universe@691 554 (void) map->cl->remove(map, key, false);
universe@691 555 }
universe@691 556
universe@691 557 /**
universe@691 558 * Detaches a key/value-pair from the map by using the key
universe@691 559 * without invoking the destructor.
universe@691 560 *
universe@691 561 * In general, you should only use this function if the map does not own
universe@691 562 * the data and there is a valid reference to the data somewhere else
universe@691 563 * in the program. In all other cases it is preferable to use
universe@691 564 * cxMapRemove() or cxMapRemoveAndGet().
universe@691 565 *
universe@691 566 * @param map the map
universe@691 567 * @param key the key
universe@691 568 * @see cxMapRemove()
universe@691 569 * @see cxMapRemoveAndGet()
universe@691 570 */
universe@691 571 __attribute__((__nonnull__))
universe@691 572 static inline void cxMapDetach(
universe@691 573 CxMap *map,
universe@691 574 cxstring const &key
universe@691 575 ) {
universe@691 576 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
universe@691 577 }
universe@691 578
universe@691 579 /**
universe@691 580 * Detaches a key/value-pair from the map by using the key
universe@691 581 * without invoking the destructor.
universe@691 582 *
universe@691 583 * In general, you should only use this function if the map does not own
universe@691 584 * the data and there is a valid reference to the data somewhere else
universe@691 585 * in the program. In all other cases it is preferable to use
universe@691 586 * cxMapRemove() or cxMapRemoveAndGet().
universe@691 587 *
universe@691 588 * @param map the map
universe@691 589 * @param key the key
universe@691 590 * @see cxMapRemove()
universe@691 591 * @see cxMapRemoveAndGet()
universe@691 592 */
universe@691 593 __attribute__((__nonnull__))
universe@691 594 static inline void cxMapDetach(
universe@691 595 CxMap *map,
universe@692 596 cxmutstr const &key
universe@692 597 ) {
universe@692 598 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
universe@692 599 }
universe@692 600
universe@692 601 /**
universe@692 602 * Detaches a key/value-pair from the map by using the key
universe@692 603 * without invoking the destructor.
universe@692 604 *
universe@692 605 * In general, you should only use this function if the map does not own
universe@692 606 * the data and there is a valid reference to the data somewhere else
universe@692 607 * in the program. In all other cases it is preferable to use
universe@692 608 * cxMapRemove() or cxMapRemoveAndGet().
universe@692 609 *
universe@692 610 * @param map the map
universe@692 611 * @param key the key
universe@692 612 * @see cxMapRemove()
universe@692 613 * @see cxMapRemoveAndGet()
universe@692 614 */
universe@692 615 __attribute__((__nonnull__))
universe@692 616 static inline void cxMapDetach(
universe@692 617 CxMap *map,
universe@691 618 char const *key
universe@691 619 ) {
universe@691 620 (void) map->cl->remove(map, cx_hash_key_str(key), false);
universe@691 621 }
universe@691 622
universe@691 623 /**
universe@691 624 * Removes a key/value-pair from the map by using the key.
universe@691 625 *
universe@691 626 * This function can be used when the map is storing pointers,
universe@691 627 * in order to retrieve the pointer from the map without invoking
universe@691 628 * any destructor function. Sometimes you do not want the pointer
universe@691 629 * to be returned - in that case (instead of suppressing the "unused
universe@691 630 * result" warning) you can use cxMapDetach().
universe@691 631 *
universe@691 632 * If this map is not storing pointers, this function behaves like
universe@691 633 * cxMapRemove() and returns \c NULL.
universe@691 634 *
universe@691 635 * @param map the map
universe@691 636 * @param key the key
universe@691 637 * @return the stored pointer or \c NULL if either the key is not present
universe@691 638 * in the map or the map is not storing pointers
universe@691 639 * @see cxMapStorePointers()
universe@691 640 * @see cxMapDetach()
universe@691 641 */
universe@691 642 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 643 static inline void *cxMapRemoveAndGet(
universe@691 644 CxMap *map,
universe@691 645 CxHashKey key
universe@691 646 ) {
universe@691 647 return map->cl->remove(map, key, !map->store_pointer);
universe@691 648 }
universe@691 649
universe@691 650 /**
universe@691 651 * Removes a key/value-pair from the map by using the key.
universe@691 652 *
universe@691 653 * This function can be used when the map is storing pointers,
universe@691 654 * in order to retrieve the pointer from the map without invoking
universe@691 655 * any destructor function. Sometimes you do not want the pointer
universe@691 656 * to be returned - in that case (instead of suppressing the "unused
universe@691 657 * result" warning) you can use cxMapDetach().
universe@691 658 *
universe@691 659 * If this map is not storing pointers, this function behaves like
universe@691 660 * cxMapRemove() and returns \c NULL.
universe@691 661 *
universe@691 662 * @param map the map
universe@691 663 * @param key the key
universe@691 664 * @return the stored pointer or \c NULL if either the key is not present
universe@691 665 * in the map or the map is not storing pointers
universe@691 666 * @see cxMapStorePointers()
universe@691 667 * @see cxMapDetach()
universe@691 668 */
universe@691 669 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 670 static inline void *cxMapRemoveAndGet(
universe@691 671 CxMap *map,
universe@691 672 cxstring key
universe@691 673 ) {
universe@691 674 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
universe@691 675 }
universe@691 676
universe@691 677 /**
universe@691 678 * Removes a key/value-pair from the map by using the key.
universe@691 679 *
universe@691 680 * This function can be used when the map is storing pointers,
universe@691 681 * in order to retrieve the pointer from the map without invoking
universe@691 682 * any destructor function. Sometimes you do not want the pointer
universe@691 683 * to be returned - in that case (instead of suppressing the "unused
universe@691 684 * result" warning) you can use cxMapDetach().
universe@691 685 *
universe@691 686 * If this map is not storing pointers, this function behaves like
universe@691 687 * cxMapRemove() and returns \c NULL.
universe@691 688 *
universe@691 689 * @param map the map
universe@691 690 * @param key the key
universe@691 691 * @return the stored pointer or \c NULL if either the key is not present
universe@691 692 * in the map or the map is not storing pointers
universe@691 693 * @see cxMapStorePointers()
universe@691 694 * @see cxMapDetach()
universe@691 695 */
universe@691 696 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 697 static inline void *cxMapRemoveAndGet(
universe@691 698 CxMap *map,
universe@692 699 cxmutstr key
universe@692 700 ) {
universe@692 701 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
universe@692 702 }
universe@692 703
universe@692 704 /**
universe@692 705 * Removes a key/value-pair from the map by using the key.
universe@692 706 *
universe@692 707 * This function can be used when the map is storing pointers,
universe@692 708 * in order to retrieve the pointer from the map without invoking
universe@692 709 * any destructor function. Sometimes you do not want the pointer
universe@692 710 * to be returned - in that case (instead of suppressing the "unused
universe@692 711 * result" warning) you can use cxMapDetach().
universe@692 712 *
universe@692 713 * If this map is not storing pointers, this function behaves like
universe@692 714 * cxMapRemove() and returns \c NULL.
universe@692 715 *
universe@692 716 * @param map the map
universe@692 717 * @param key the key
universe@692 718 * @return the stored pointer or \c NULL if either the key is not present
universe@692 719 * in the map or the map is not storing pointers
universe@692 720 * @see cxMapStorePointers()
universe@692 721 * @see cxMapDetach()
universe@692 722 */
universe@692 723 __attribute__((__nonnull__, __warn_unused_result__))
universe@692 724 static inline void *cxMapRemoveAndGet(
universe@692 725 CxMap *map,
universe@691 726 char const *key
universe@691 727 ) {
universe@691 728 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
universe@691 729 }
universe@691 730
universe@691 731 #else // __cplusplus
universe@691 732
universe@691 733 /**
universe@691 734 * Puts a key/value-pair into the map.
universe@691 735 *
universe@691 736 * @param map the map
universe@691 737 * @param key the key
universe@691 738 * @param value the value
universe@691 739 * @return 0 on success, non-zero value on failure
universe@691 740 */
universe@691 741 __attribute__((__nonnull__))
universe@691 742 static inline int cx_map_put(
universe@691 743 CxMap *map,
universe@691 744 CxHashKey key,
universe@691 745 void *value
universe@691 746 ) {
universe@691 747 return map->cl->put(map, key, value);
universe@691 748 }
universe@691 749
universe@691 750 /**
universe@691 751 * Puts a key/value-pair into the map.
universe@691 752 *
universe@691 753 * @param map the map
universe@691 754 * @param key the key
universe@691 755 * @param value the value
universe@691 756 * @return 0 on success, non-zero value on failure
universe@691 757 */
universe@691 758 __attribute__((__nonnull__))
universe@691 759 static inline int cx_map_put_cxstr(
universe@691 760 CxMap *map,
universe@691 761 cxstring key,
universe@691 762 void *value
universe@691 763 ) {
universe@691 764 return map->cl->put(map, cx_hash_key_cxstr(key), value);
universe@691 765 }
universe@691 766
universe@691 767 /**
universe@691 768 * Puts a key/value-pair into the map.
universe@691 769 *
universe@691 770 * @param map the map
universe@691 771 * @param key the key
universe@691 772 * @param value the value
universe@691 773 * @return 0 on success, non-zero value on failure
universe@691 774 */
universe@691 775 __attribute__((__nonnull__))
universe@692 776 static inline int cx_map_put_mustr(
universe@692 777 CxMap *map,
universe@692 778 cxmutstr key,
universe@692 779 void *value
universe@692 780 ) {
universe@692 781 return map->cl->put(map, cx_hash_key_cxstr(key), value);
universe@692 782 }
universe@692 783
universe@692 784 /**
universe@692 785 * Puts a key/value-pair into the map.
universe@692 786 *
universe@692 787 * @param map the map
universe@692 788 * @param key the key
universe@692 789 * @param value the value
universe@692 790 * @return 0 on success, non-zero value on failure
universe@692 791 */
universe@692 792 __attribute__((__nonnull__))
universe@691 793 static inline int cx_map_put_str(
universe@691 794 CxMap *map,
universe@691 795 char const *key,
universe@691 796 void *value
universe@691 797 ) {
universe@691 798 return map->cl->put(map, cx_hash_key_str(key), value);
universe@691 799 }
universe@691 800
universe@691 801 /**
universe@691 802 * Puts a key/value-pair into the map.
universe@691 803 *
universe@691 804 * @param map the map
universe@691 805 * @param key the key
universe@691 806 * @param value the value
universe@691 807 * @return 0 on success, non-zero value on failure
universe@691 808 */
universe@691 809 #define cxMapPut(map, key, value) _Generic((key), \
universe@691 810 CxHashKey: cx_map_put, \
universe@691 811 cxstring: cx_map_put_cxstr, \
universe@692 812 cxmutstr: cx_map_put_mustr, \
universe@694 813 char*: cx_map_put_str, \
universe@694 814 char const*: cx_map_put_str) \
universe@691 815 (map, key, value)
universe@691 816
universe@691 817 /**
universe@691 818 * Retrieves a value by using a key.
universe@691 819 *
universe@691 820 * @param map the map
universe@691 821 * @param key the key
universe@691 822 * @return the value
universe@691 823 */
universe@691 824 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 825 static inline void *cx_map_get(
universe@691 826 CxMap const *map,
universe@691 827 CxHashKey key
universe@691 828 ) {
universe@691 829 return map->cl->get(map, key);
universe@691 830 }
universe@691 831
universe@691 832 /**
universe@691 833 * Retrieves a value by using a key.
universe@691 834 *
universe@691 835 * @param map the map
universe@691 836 * @param key the key
universe@691 837 * @return the value
universe@691 838 */
universe@691 839 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 840 static inline void *cx_map_get_cxstr(
universe@691 841 CxMap const *map,
universe@691 842 cxstring key
universe@691 843 ) {
universe@691 844 return map->cl->get(map, cx_hash_key_cxstr(key));
universe@691 845 }
universe@691 846
universe@691 847 /**
universe@691 848 * Retrieves a value by using a key.
universe@691 849 *
universe@691 850 * @param map the map
universe@691 851 * @param key the key
universe@691 852 * @return the value
universe@691 853 */
universe@691 854 __attribute__((__nonnull__, __warn_unused_result__))
universe@692 855 static inline void *cx_map_get_mustr(
universe@692 856 CxMap const *map,
universe@692 857 cxmutstr key
universe@692 858 ) {
universe@692 859 return map->cl->get(map, cx_hash_key_cxstr(key));
universe@692 860 }
universe@692 861
universe@692 862 /**
universe@692 863 * Retrieves a value by using a key.
universe@692 864 *
universe@692 865 * @param map the map
universe@692 866 * @param key the key
universe@692 867 * @return the value
universe@692 868 */
universe@692 869 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 870 static inline void *cx_map_get_str(
universe@691 871 CxMap const *map,
universe@691 872 char const *key
universe@691 873 ) {
universe@691 874 return map->cl->get(map, cx_hash_key_str(key));
universe@691 875 }
universe@691 876
universe@691 877 /**
universe@691 878 * Retrieves a value by using a key.
universe@691 879 *
universe@691 880 * @param map the map
universe@691 881 * @param key the key
universe@691 882 * @return the value
universe@691 883 */
universe@691 884 #define cxMapGet(map, key) _Generic((key), \
universe@691 885 CxHashKey: cx_map_get, \
universe@691 886 cxstring: cx_map_get_cxstr, \
universe@692 887 cxmutstr: cx_map_get_mustr, \
universe@694 888 char*: cx_map_get_str, \
universe@694 889 char const*: cx_map_get_str) \
universe@691 890 (map, key)
universe@691 891
universe@691 892 /**
universe@691 893 * Removes a key/value-pair from the map by using the key.
universe@691 894 *
universe@691 895 * @param map the map
universe@691 896 * @param key the key
universe@691 897 */
universe@691 898 __attribute__((__nonnull__))
universe@691 899 static inline void cx_map_remove(
universe@691 900 CxMap *map,
universe@691 901 CxHashKey key
universe@691 902 ) {
universe@691 903 (void) map->cl->remove(map, key, true);
universe@691 904 }
universe@691 905
universe@691 906 /**
universe@691 907 * Removes a key/value-pair from the map by using the key.
universe@691 908 *
universe@691 909 * @param map the map
universe@691 910 * @param key the key
universe@691 911 */
universe@691 912 __attribute__((__nonnull__))
universe@691 913 static inline void cx_map_remove_cxstr(
universe@691 914 CxMap *map,
universe@691 915 cxstring key
universe@691 916 ) {
universe@691 917 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
universe@691 918 }
universe@691 919
universe@691 920 /**
universe@691 921 * Removes a key/value-pair from the map by using the key.
universe@691 922 *
universe@691 923 * @param map the map
universe@691 924 * @param key the key
universe@691 925 */
universe@691 926 __attribute__((__nonnull__))
universe@692 927 static inline void cx_map_remove_mustr(
universe@692 928 CxMap *map,
universe@692 929 cxmutstr key
universe@692 930 ) {
universe@692 931 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
universe@692 932 }
universe@692 933
universe@692 934 /**
universe@692 935 * Removes a key/value-pair from the map by using the key.
universe@692 936 *
universe@692 937 * @param map the map
universe@692 938 * @param key the key
universe@692 939 */
universe@692 940 __attribute__((__nonnull__))
universe@691 941 static inline void cx_map_remove_str(
universe@691 942 CxMap *map,
universe@691 943 char const *key
universe@691 944 ) {
universe@691 945 (void) map->cl->remove(map, cx_hash_key_str(key), true);
universe@691 946 }
universe@691 947
universe@691 948 /**
universe@691 949 * Removes a key/value-pair from the map by using the key.
universe@691 950 *
universe@691 951 * Always invokes the destructor function, if any, on the removed element.
universe@691 952 * If this map is storing pointers and you just want to retrieve the pointer
universe@691 953 * without invoking the destructor, use cxMapRemoveAndGet().
universe@691 954 * If you just want to detach the element from the map without invoking the
universe@691 955 * destructor or returning the element, use cxMapDetach().
universe@691 956 *
universe@691 957 * @param map the map
universe@691 958 * @param key the key
universe@691 959 * @see cxMapRemoveAndGet()
universe@691 960 * @see cxMapDetach()
universe@691 961 */
universe@691 962 #define cxMapRemove(map, key) _Generic((key), \
universe@691 963 CxHashKey: cx_map_remove, \
universe@691 964 cxstring: cx_map_remove_cxstr, \
universe@692 965 cxmutstr: cx_map_remove_mustr, \
universe@694 966 char*: cx_map_remove_str, \
universe@694 967 char const*: cx_map_remove_str) \
universe@691 968 (map, key)
universe@691 969
universe@691 970 /**
universe@691 971 * Detaches a key/value-pair from the map by using the key
universe@691 972 * without invoking the destructor.
universe@691 973 *
universe@691 974 * @param map the map
universe@691 975 * @param key the key
universe@691 976 */
universe@691 977 __attribute__((__nonnull__))
universe@691 978 static inline void cx_map_detach(
universe@691 979 CxMap *map,
universe@691 980 CxHashKey key
universe@691 981 ) {
universe@691 982 (void) map->cl->remove(map, key, false);
universe@691 983 }
universe@691 984
universe@691 985 /**
universe@691 986 * Detaches a key/value-pair from the map by using the key
universe@691 987 * without invoking the destructor.
universe@691 988 *
universe@691 989 * @param map the map
universe@691 990 * @param key the key
universe@691 991 */
universe@691 992 __attribute__((__nonnull__))
universe@691 993 static inline void cx_map_detach_cxstr(
universe@691 994 CxMap *map,
universe@691 995 cxstring key
universe@691 996 ) {
universe@691 997 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
universe@691 998 }
universe@691 999
universe@691 1000 /**
universe@691 1001 * Detaches a key/value-pair from the map by using the key
universe@691 1002 * without invoking the destructor.
universe@691 1003 *
universe@691 1004 * @param map the map
universe@691 1005 * @param key the key
universe@691 1006 */
universe@691 1007 __attribute__((__nonnull__))
universe@692 1008 static inline void cx_map_detach_mustr(
universe@692 1009 CxMap *map,
universe@692 1010 cxmutstr key
universe@692 1011 ) {
universe@692 1012 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
universe@692 1013 }
universe@692 1014
universe@692 1015 /**
universe@692 1016 * Detaches a key/value-pair from the map by using the key
universe@692 1017 * without invoking the destructor.
universe@692 1018 *
universe@692 1019 * @param map the map
universe@692 1020 * @param key the key
universe@692 1021 */
universe@692 1022 __attribute__((__nonnull__))
universe@691 1023 static inline void cx_map_detach_str(
universe@691 1024 CxMap *map,
universe@691 1025 char const *key
universe@691 1026 ) {
universe@691 1027 (void) map->cl->remove(map, cx_hash_key_str(key), false);
universe@691 1028 }
universe@691 1029
universe@691 1030 /**
universe@691 1031 * Detaches a key/value-pair from the map by using the key
universe@691 1032 * without invoking the destructor.
universe@691 1033 *
universe@691 1034 * In general, you should only use this function if the map does not own
universe@691 1035 * the data and there is a valid reference to the data somewhere else
universe@691 1036 * in the program. In all other cases it is preferable to use
universe@691 1037 * cxMapRemove() or cxMapRemoveAndGet().
universe@691 1038 *
universe@691 1039 * @param map the map
universe@691 1040 * @param key the key
universe@691 1041 * @see cxMapRemove()
universe@691 1042 * @see cxMapRemoveAndGet()
universe@691 1043 */
universe@691 1044 #define cxMapDetach(map, key) _Generic((key), \
universe@691 1045 CxHashKey: cx_map_detach, \
universe@691 1046 cxstring: cx_map_detach_cxstr, \
universe@692 1047 cxmutstr: cx_map_detach_mustr, \
universe@694 1048 char*: cx_map_detach_str, \
universe@694 1049 char const*: cx_map_detach_str) \
universe@691 1050 (map, key)
universe@691 1051
universe@691 1052 /**
universe@691 1053 * Removes a key/value-pair from the map by using the key.
universe@691 1054 *
universe@691 1055 * @param map the map
universe@691 1056 * @param key the key
universe@691 1057 * @return the stored pointer or \c NULL if either the key is not present
universe@691 1058 * in the map or the map is not storing pointers
universe@691 1059 */
universe@691 1060 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 1061 static inline void *cx_map_remove_and_get(
universe@691 1062 CxMap *map,
universe@691 1063 CxHashKey key
universe@691 1064 ) {
universe@691 1065 return map->cl->remove(map, key, !map->store_pointer);
universe@691 1066 }
universe@691 1067
universe@691 1068 /**
universe@691 1069 * Removes a key/value-pair from the map by using the key.
universe@691 1070 *
universe@691 1071 * @param map the map
universe@691 1072 * @param key the key
universe@691 1073 * @return the stored pointer or \c NULL if either the key is not present
universe@691 1074 * in the map or the map is not storing pointers
universe@691 1075 */
universe@691 1076 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 1077 static inline void *cx_map_remove_and_get_cxstr(
universe@691 1078 CxMap *map,
universe@691 1079 cxstring key
universe@691 1080 ) {
universe@691 1081 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
universe@691 1082 }
universe@691 1083
universe@691 1084 /**
universe@691 1085 * Removes a key/value-pair from the map by using the key.
universe@691 1086 *
universe@691 1087 * @param map the map
universe@691 1088 * @param key the key
universe@691 1089 * @return the stored pointer or \c NULL if either the key is not present
universe@691 1090 * in the map or the map is not storing pointers
universe@691 1091 */
universe@691 1092 __attribute__((__nonnull__, __warn_unused_result__))
universe@692 1093 static inline void *cx_map_remove_and_get_mustr(
universe@692 1094 CxMap *map,
universe@692 1095 cxmutstr key
universe@692 1096 ) {
universe@692 1097 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
universe@692 1098 }
universe@692 1099
universe@692 1100 /**
universe@692 1101 * Removes a key/value-pair from the map by using the key.
universe@692 1102 *
universe@692 1103 * @param map the map
universe@692 1104 * @param key the key
universe@692 1105 * @return the stored pointer or \c NULL if either the key is not present
universe@692 1106 * in the map or the map is not storing pointers
universe@692 1107 */
universe@692 1108 __attribute__((__nonnull__, __warn_unused_result__))
universe@691 1109 static inline void *cx_map_remove_and_get_str(
universe@691 1110 CxMap *map,
universe@691 1111 char const *key
universe@691 1112 ) {
universe@691 1113 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
universe@691 1114 }
universe@691 1115
universe@691 1116 /**
universe@691 1117 * Removes a key/value-pair from the map by using the key.
universe@691 1118 *
universe@691 1119 * This function can be used when the map is storing pointers,
universe@691 1120 * in order to retrieve the pointer from the map without invoking
universe@691 1121 * any destructor function. Sometimes you do not want the pointer
universe@691 1122 * to be returned - in that case (instead of suppressing the "unused
universe@691 1123 * result" warning) you can use cxMapDetach().
universe@691 1124 *
universe@691 1125 * If this map is not storing pointers, this function behaves like
universe@691 1126 * cxMapRemove() and returns \c NULL.
universe@691 1127 *
universe@691 1128 * @param map the map
universe@691 1129 * @param key the key
universe@691 1130 * @return the stored pointer or \c NULL if either the key is not present
universe@691 1131 * in the map or the map is not storing pointers
universe@691 1132 * @see cxMapStorePointers()
universe@691 1133 * @see cxMapDetach()
universe@691 1134 */
universe@691 1135 #define cxMapRemoveAndGet(map, key) _Generic((key), \
universe@691 1136 CxHashKey: cx_map_remove_and_get, \
universe@691 1137 cxstring: cx_map_remove_and_get_cxstr, \
universe@692 1138 cxmutstr: cx_map_remove_and_get_mustr, \
universe@694 1139 char*: cx_map_remove_and_get_str, \
universe@694 1140 char const*: cx_map_remove_and_get_str) \
universe@691 1141 (map, key)
universe@691 1142
universe@691 1143 #endif // __cplusplus
universe@691 1144
universe@691 1145 #endif // UCX_MAP_H

mercurial