Skip to content

Map

Map

Description

Typesafe multimap definition.

This behaves like the other generic containers in the project: each use of Map(K, V) creates a distinct anonymous type, so reusable aliases should be defined with typedef. Multiple values may be stored for the same key.

Fields

Name Description
length Number of stored key/value pairs, including duplicate keys.
capacity Total number of probe slots currently allocated.
tombstones Number of deleted slots currently retained for probing.
key_copy_init Optional deep-copy callback for keys.
key_copy_deinit Optional deinit callback for keys held by the map.
value_copy_init Optional deep-copy callback for values.
value_copy_deinit Optional deinit callback for values held by the map.
key_compare Required comparator for keys. Equality is compare == 0.
value_compare Optional comparator for values. Required for pair-level APIs.
key_hash Required hash callback for keys.
entries Pointer to entry storage. Do not index directly.
states Slot-state storage used internally by the probing policy.
policy Copy of the probing policy used by this map.

Usage example (from documentation)

  typedef Map(int, Str) IntStrMap;
  typedef Map(T(Pair(i32, i32)), float) PairFloatMap;

Usage example (Cross-references)

Usage examples (Cross-references)
    /// Generic map implementation
    
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Sys.h>
        limit = map->policy.max_probe_count;
        if (limit == 0) {
            LOG_FATAL("Map policy '{}' has invalid max_probe_count", map->policy.name);
        }
    void validate_map(const GenericMap *map) {
        if (!map) {
            LOG_FATAL("Expected a valid Map pointer");
        }
    
        if (map->__magic != MISRA_MAP_MAGIC) {
            LOG_FATAL("Map is uninitialized or corrupted");
        }
    
        if (!map->key_compare || !map->key_hash) {
            LOG_FATAL("Map must have valid key compare and key hash callbacks");
        }
    
        if (map->length > map->capacity) {
            LOG_FATAL("Map length cannot exceed capacity");
        }
    
        if ((map->length + map->tombstones) > map->capacity) {
            LOG_FATAL("Map occupied slots and tombstones cannot exceed capacity");
        }
        if (!map->capacity) {
            if (map->entries || map->states) {
                LOG_FATAL("Map with zero capacity must not have allocated storage");
            }
            return;
    
        if (!map->entries || !map->states) {
            LOG_FATAL("Map storage is corrupted");
        }
    }
    
        if (new_capacity < (n > map->length ? n : (size)map->length)) {
            LOG_FATAL("Map policy '{}' returned insufficient capacity {}", policy.name, new_capacity);
        }
    #include <Misra/Parsers/KvConfig.h>
    #include <Misra/Std/Container/Map/Private.h>
    #include <Misra/Std/Memory.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_type_defaults(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_type_with_value_compare(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInitWithValueCompare(int_hash, int_compare, int_compare);
    
    static bool test_map_policy_copy(void) {
        typedef Map(int, int) IntIntMap;
        MapPolicy custom_policy = {
            .name            = "custom-linear",
        };
    
        WriteFmt("[INFO] Starting Map.Type tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Type");
    }
    
        WriteFmt("[INFO] Starting Map.Type tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Type");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_remove_value(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_remove_pair(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInitWithValueCompare(int_hash, int_compare, int_compare);
    
    static bool test_map_remove_if(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_remove_all(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_tombstone_reuse(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
        };
    
        WriteFmt("[INFO] Starting Map.Remove tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Remove");
    }
    
        WriteFmt("[INFO] Starting Map.Remove tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Remove");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_foreach_ptr(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map       = MapInit(int_hash, int_compare);
        int       key_sum   = 0;
    
    static bool test_map_foreach_multimap_iterators(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map            = MapInit(int_hash, int_compare);
        int       unique_key_sum = 0;
        };
    
        WriteFmt("[INFO] Starting Map.Foreach tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Foreach");
    }
    
        WriteFmt("[INFO] Starting Map.Foreach tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Foreach");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_insert_and_set(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_set_first(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInitWithValueCompare(int_hash, int_compare, int_compare);
    
    static bool test_map_lvalue_zeroing(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map   = MapInit(int_hash, int_compare);
        int       key   = 42;
    
    static bool test_map_ensure_ptr(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
        int      *value_ptr;
        };
    
        WriteFmt("[INFO] Starting Map.Insert tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Insert");
    }
    
        WriteFmt("[INFO] Starting Map.Insert tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Insert");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Memory.h>
    
    static bool test_map_deep_copy_zstrs(void) {
        typedef Map(const char *, const char *) ZstrMap;
        ZstrMap map =
            MapInitWithDeepCopy(zstr_hash, zstr_compare_ptr, ZstrInitClone, ZstrDeinit, ZstrInitClone, ZstrDeinit);
    
    static bool test_map_policy_switch_preserves_entries(void) {
        typedef Map(const char *, const char *) ZstrMap;
        ZstrMap map =
            MapInitWithDeepCopy(zstr_hash, zstr_compare_ptr, ZstrInitClone, ZstrDeinit, ZstrInitClone, ZstrDeinit);
    
    static bool test_map_compact_and_swap(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap first  = MapInitWithValueCompare(int_hash, int_compare, int_compare);
        IntIntMap second = MapInitWithValueCompare(int_hash, int_compare, int_compare);
    
    static bool test_map_retain_if(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map       = MapInit(int_hash, int_compare);
        int       threshold = 30;
        };
    
        WriteFmt("[INFO] Starting Map.Ops tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Ops");
    }
    
        WriteFmt("[INFO] Starting Map.Ops tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Ops");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_reserve_and_clear(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_rehash_policy_switch(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_custom_policy_growth(void) {
        typedef Map(int, int) IntIntMap;
        MapPolicy custom_policy = {
            .name            = "five-step",
        };
    
        WriteFmt("[INFO] Starting Map.Init tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Init");
    }
    
        WriteFmt("[INFO] Starting Map.Init tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Init");
    }
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../Util/TestRunner.h"
    
    static bool test_map_contains_and_find(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInitWithValueCompare(int_hash, int_compare, int_compare);
    
    static bool test_map_get_ptr(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap map = MapInit(int_hash, int_compare);
    
    static bool test_map_value_cursor_query(void) {
        typedef Map(int, int) IntIntMap;
        IntIntMap      map       = MapInit(int_hash, int_compare);
        MapValueCursor cursor    = MapValueCursorInvalid();
        };
    
        WriteFmt("[INFO] Starting Map.Access tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Access");
    }
    
        WriteFmt("[INFO] Starting Map.Access tests\n\n");
        return run_test_suite(tests, (int)(sizeof(tests) / sizeof(tests[0])), NULL, 0, "Map.Access");
    }
    #include <Misra/Std/Container/Vec.h>
    #include <Misra/Std/Container/List.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/BitVec.h>
    #include <Misra/Std/Container/Int.h>
    
    // clang-format off
    #include "Map/Type.h"
    #include "Map/Init.h"
    #include "Map/Insert.h"
    // clang-format off
    #include "Map/Type.h"
    #include "Map/Init.h"
    #include "Map/Insert.h"
    #include "Map/Remove.h"
    #include "Map/Type.h"
    #include "Map/Init.h"
    #include "Map/Insert.h"
    #include "Map/Remove.h"
    #include "Map/Access.h"
    #include "Map/Init.h"
    #include "Map/Insert.h"
    #include "Map/Remove.h"
    #include "Map/Access.h"
    #include "Map/Memory.h"
    #include "Map/Insert.h"
    #include "Map/Remove.h"
    #include "Map/Access.h"
    #include "Map/Memory.h"
    #include "Map/Foreach.h"
    #include "Map/Remove.h"
    #include "Map/Access.h"
    #include "Map/Memory.h"
    #include "Map/Foreach.h"
    #include "Map/Ops.h"
    #include "Map/Access.h"
    #include "Map/Memory.h"
    #include "Map/Foreach.h"
    #include "Map/Ops.h"
    #include "Map/Private.h"
    #include "Map/Memory.h"
    #include "Map/Foreach.h"
    #include "Map/Ops.h"
    #include "Map/Private.h"
    // clang-format on
    #include "Map/Foreach.h"
    #include "Map/Ops.h"
    #include "Map/Private.h"
    // clang-format on
    #define MISRA_PARSERS_KVCONFIG_H
    
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Utility/StrIter.h>
    /// TAGS: Parser, Config, KeyValue, Map
    ///
    typedef Map(Str, Str) KvConfig;
    
    ///
Last updated on