Skip to content

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)
    #endif
    #if FEATURE_MAP
    #    include <Misra/Std/Container/Map.h>
    #endif
    #if FEATURE_GRAPH
    
    // 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
    #include <Misra/Std/Allocator/Heap.h>
    #include <Misra/Std/Allocator/Page.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Container/Vec.h>
        } DebugRecord;
    
        typedef Map(void *, DebugRecord) DebugRecordMap;
    
        ///
    #define MISRA_PARSERS_KVCONFIG_H
    
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Utility/StrIter.h>
    // translation-unit-visible spot so the public header and the
    // implementation agree on the layout.
    typedef Map(Str, Str) KvConfig;
    
    // Private backends. Included AFTER the KvConfig typedef so the
    /// Generic map implementation
    
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Std/Memory.h>
        limit = map->policy.max_probe_count;
        if (limit == 0) {
            LOG_FATAL("Map policy '{}' has invalid max_probe_count", map->policy.name);
        }
    static void validate_map_structural(const GenericMap *map) {
        if (!map->key_compare || !map->key_hash) {
            LOG_FATAL("Map must have valid key compare and key hash callbacks");
        }
        if (!map->allocator) {
        }
        if (!map->allocator) {
            LOG_FATAL("Map allocator pointer is NULL");
        }
        if (!map->allocator->allocate || !map->allocator->resize || !map->allocator->remap || !map->allocator->deallocate) {
        }
        if (!map->allocator->allocate || !map->allocator->resize || !map->allocator->remap || !map->allocator->deallocate) {
            LOG_FATAL("Map allocator is invalid");
        }
        validate_map_policy(&map->policy);
        validate_map_policy(&map->policy);
        if (map->length > map->capacity) {
            LOG_FATAL("Map length cannot exceed capacity");
        }
        if ((map->length + map->tombstones) > map->capacity) {
        }
        if ((map->length + map->tombstones) > map->capacity) {
            LOG_FATAL("Map occupied slots and tombstones cannot exceed capacity");
        }
        if (!map->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");
        }
    }
    void validate_map(const GenericMap *map) {
        if (!map) {
            LOG_FATAL("Expected a valid Map pointer");
        }
        if (!MAGIC_MATCHES(map->__magic, MAP_MAGIC)) {
        }
        if (!MAGIC_MATCHES(map->__magic, MAP_MAGIC)) {
            LOG_FATAL("Map is uninitialized or corrupted");
        }
        if (!(map->__magic & MAGIC_VALIDATED_BIT)) {
    
        if (new_capacity < (n > map->length ? n : (size)map->length)) {
            LOG_FATAL("Map policy '{}' returned insufficient capacity {}", policy.name, new_capacity);
        }
    
    #include <Misra/Std.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Std/Memory.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Graph.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Log.h>
    
    typedef Graph(Str) CityGraph;
    typedef Map(Str, GraphNodeId) CityIndex;
    
    static GraphNodeId city_add_intersection(CityGraph *graph, CityIndex *index, const Str *name, DefaultAllocator *alloc) {
    
        typedef Graph(int) IntGraph;
        typedef Map(GraphNodeId, u64) CountMap;
    
        IntGraph graph  = GraphInit(&alloc);
    #include <Misra/Std/Container/Float.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    // the GenericHash / GenericCompare-shaped helpers wire in directly.
    bool test_float_hash_as_map_key(void) {
        WriteFmt("Testing float_hash as Map<Float, u64> key\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Map(Float, u64) counts = MapInit(float_hash, float_compare, &alloc);
    
        Float k1 = FloatFromStr("3.14", &alloc.base);
    #include <Misra/Std/Container/BitVec.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Log.h>
    // shaped helpers wired in directly -- no per-callsite cast needed.
    bool test_bitvec_hash_as_map_key(void) {
        WriteFmt("Testing bitvec_hash as Map<BitVec, u64> key\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        Allocator       *base  = ALLOCATOR_OF(&alloc);
    
        Map(BitVec, u64) counts = MapInit(bitvec_hash, bitvec_compare, &alloc);
    
        BitVec k1 = BitVecInit(base);
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Container/Int.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Types.h>
    // GenericHash / GenericCompare-shaped helpers wire in directly.
    bool test_int_hash_as_map_key(void) {
        WriteFmt("Testing int_hash as Map<Int,u64> key\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Map(Int, u64) counts = MapInit(int_hash, int_compare, &alloc);
    
        Int k1 = IntFrom(100u, &alloc.base);
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #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(Zstr, Zstr) ZstrMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        ZstrMap          map   = MapInitWithDeepCopy(
    
    static bool test_map_policy_switch_preserves_entries(void) {
        typedef Map(Zstr, Zstr) ZstrMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        ZstrMap          map   = MapInitWithDeepCopy(
    
    static bool test_map_compact_and_swap(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        IntIntMap        first  = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // pair is removed/cleared.
    static bool test_map_empty_true_and_false(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // preserved, length exact) happened and control returned to the caller.
    static bool test_map_must_compact_success(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // live entry survives the rehash, tombstones gone, and control returned.
    static bool test_map_must_rehash_with_policy_success(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    
    static bool test_map_retain_if(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc     = DefaultAllocatorInit();
        IntIntMap        map       = MapInit(i32_hash, i32_compare, &alloc);
    // the stale zeroed slot ahead of the real entry.
    static bool test_clear_resets_slots_to_empty(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(const_hash, i32_compare, i32_compare, &alloc);
        };
    
        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/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Log.h>
    
    static bool test_map_reserve_and_clear(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_rehash_policy_switch(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_custom_policy_growth(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc         = DefaultAllocatorInit();
        MapPolicy        custom_policy = {
    
    static bool test_map_init_defaults_are_linear(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_reserve_preserves_entries(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_must_reserve(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_init_typed(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitT(map, i32_hash, i32_compare, &alloc);
    
    static bool test_map_init_deep_copy_typed(void) {
        typedef Map(Zstr, Zstr) ZstrMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        ZstrMap          map   = MapInitWithDeepCopyT(
    // to force several growths.
    static bool test_map_grows_to_fit_many_inserts(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        };
    
        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/Allocator/Default.h>
    #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;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_set_first(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // miss (or the header claiming it does) turns this RED.
    static bool test_map_set_first_miss_returns_false(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // map_remove_all step would leave the old duplicates behind.
    static bool test_map_set_only_collapses_multi(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    
    static bool test_map_lvalue_zeroing(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // never through map_zero_insert_sources_on_success.
    static bool test_map_rvalue_does_not_zero_sources(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // the set_only_l form.
    static bool test_map_set_only_lvalue_zeroing(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // set_first_l form (zero only on success).
    static bool test_map_set_first_lvalue_zeroing(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // would re-probe the same cluster and loop forever).
    static bool test_map_churn_does_not_loop(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        IntIntMap        map    = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_ensure_ptr(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // that map_ensure_value_ptr returns the in-table slot, not a copy.
    static bool test_map_ensure_ptr_mutation_persists(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // replace semantics). Guards the aliasing #defines in Insert.h.
    static bool test_map_default_aliases(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // assert each MapMust* applies the same effect as its fallible form.
    static bool test_map_must_family_success(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
        WriteFmt("Testing MapRehashWithPolicy validates the new policy up front\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // breaks MapCompact on a fresh/empty map.
    static bool test_compact_empty_map_succeeds(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // empty MapCompact must leave the map valid for further use.
    static bool test_compact_empty_then_insert_length(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_compact_empty_then_insert_capacity(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_compact_empty_then_insert_tombstones(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // valid and must be accepted.
    static bool test_rehash_tight_capacity_accepted(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapRehashWithPolicy rejects under-sized capacity for n<length\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // so the map stays consistent (FAILURE contract: map unchanged).
    static bool test_rehash_alloc_failure_keeps_map_usable(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator inner = DefaultAllocatorInit();
        FailAlloc        fa    = fail_alloc_init(&inner);
    // exhausts the 4-probe budget; one doubling (to 16) splits them and succeeds.
    static bool run_doubling_retry_compact(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = make_small_probe_policy();
    // crosses the 3/4 load threshold and must grow.
    static bool test_map_preemptive_grow_succeeds(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        IntIntMap        map    = MapInit(i32_hash, i32_compare, &alloc);
    // succeed by taking the forced-grow recovery path.
    static bool test_map_probe_exhaustion_recovers(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = fill_then_grow_policy();
    // Mutant 1008 (`tombstones -= 1` -> `+= 1` when reusing a tombstone slot).
    static bool test_map_tombstone_reuse_decrements(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // fails to copy must restore the tombstone count to its pre-insert value.
    static bool test_map_tombstone_rollback_on_copy_fail(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap map = MapInitWithDeepCopy(i32_hash, i32_compare, NULL, NULL, toggled_value_copy_init, NULL, &alloc);
    // and retries. The mutant lets it slip into an out-of-bounds write.
    static bool test_insert_raw_entry_grows_on_budget_exhaustion(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = {
    // current capacity.
    static bool test_reserve_grows_when_target_exceeds_capacity(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = make_policy42();
    // Real code is at capacity 16 by the 7th insert.
    static bool test_default_grow_uses_multiply_not_divide(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // survive.
    static bool test_default_rehash_inclusive_at_boundary(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // mutant doubles once more to 16.
    static bool test_next_capacity_doubling_strict_less(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // decrements the tombstone count back to 0; the mutant inflates it.
    static bool test_setonly_raw_reinsert_decrements_tombstones(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // not the resulting capacity.
    static bool test_probe_recovery_forced_n_is_capacity_plus_one(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = fill_then_grow_policy();
        };
    
        WriteFmt("[INFO] Starting Map.Insert tests\n\n");
        return run_test_suite(
            tests,
            deadend_tests,
            (int)(sizeof(deadend_tests) / sizeof(deadend_tests[0])),
            "Map.Insert"
        );
    }
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Zstr.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Container/Str.h>
    #include <Misra/Std/Log.h>
    
    static bool test_map_type_defaults(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_type_with_value_compare(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    
    static bool test_map_policy_copy(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc         = DefaultAllocatorInit();
        MapPolicy        custom_policy = {
    
    static bool test_map_type_value_compare_and_policy(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc         = DefaultAllocatorInit();
        MapPolicy        custom_policy = {
    
    static bool test_map_type_deep_copy_wiring(void) {
        typedef Map(Zstr, Zstr) ZstrMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        ZstrMap          map   = MapInitWithDeepCopy(
        };
    
        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/Allocator/Default.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    // as length + tombstones <= capacity. Real code validates cleanly.
    static bool test_validate_more_tombstones_than_live_is_valid(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing ValidateMap on uninitialized map\n");
    
        Map(int, int) map = {0};
        ValidateMap(&map);
        WriteFmt("Testing ValidateMap with corrupted magic\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapContainsPair without value comparator\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapRemovePair without value comparator\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapRemoveIf without predicate\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapRetainIf without predicate\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing MapInitWithPolicy with an invalid policy\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = valid_baseline_policy();
        WriteFmt("Testing ValidateMap with corrupted policy name\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        WriteFmt("Testing ValidateMap with length exceeding capacity\n");
    
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        g->__magic    |= MAGIC_VALIDATED_BIT;
    
        ValidateMap(&map);                // must abort: "Map length cannot exceed capacity"
    
        return false;
    // -> a normal test that aborts = mutant killed.
    static bool test_self_check_accepts_policy_sufficient_for_real_snapshots(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = {
    
    static bool deadend_self_check_stuck_at_cap8(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = make_probe_policy(poly_next_index_stuck_at_cap8);
    
    static bool deadend_self_check_stuck_at_golden_hash(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = make_probe_policy(poly_next_index_stuck_at_golden);
    
    static bool deadend_self_check_first_index_compare(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = make_probe_policy(poly_next_index_returns_first);
    // harness counts the abort as a failure of this normal test -> mutant killed.
    static bool test_validate_skips_structural_after_first_op(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        };
    
        WriteFmt("[INFO] Starting Map.Deadend tests\n\n");
        return run_test_suite(
            tests,
            deadend_tests,
            (int)(sizeof(deadend_tests) / sizeof(deadend_tests[0])),
            "Map.Deadend"
        );
    }
    #include <Misra/Std/Allocator/Debug.h>
    #include <Misra/Std/Allocator/Default.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include <Misra/Std/Zstr.h>
    // untouched.
    static bool test_map_remove_value(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // the map completely unchanged (no spurious tombstone, no length change).
    static bool test_map_remove_first_missing_returns_false(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_remove_pair(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // absent) and the missing-key case.
    static bool test_map_remove_pair_no_match_returns_false(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // the same key reclaims it, restoring the tombstone count to zero.
    static bool test_remove_then_reinsert_reclaims_tombstone(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // iterations and return 0; the mutant dereferences the NULL states array.
    static bool test_retain_if_on_empty_map_returns_zero(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // 0; the mutant dereferences states[0] through a NULL pointer.
    static bool test_remove_if_on_empty_map_returns_zero(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_remove_if(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_remove_all(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // unchanged. Guards the FAILURE contract of map_remove_all.
    static bool test_map_remove_all_missing_returns_zero(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // deletion-strategy details rather than contract.
    static bool test_map_remove_then_reinsert_same_key(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // callbacks, the clones would leak and the live count would be non-zero.
    static bool test_map_deep_copy_deinit_on_remove(void) {
        typedef Map(Zstr, Zstr) ZstrMap;
        DebugAllocator dbg = DebugAllocatorInit();
        // Deep-copy callbacks for both key and value, plus a value comparator
    // equally correct).
    static bool test_map_collision_chain_survives_deletion(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(const_hash, i32_compare, &alloc);
        };
    
        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/Allocator/Default.h>
    #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;
        DefaultAllocator alloc     = DefaultAllocatorInit();
        IntIntMap        map       = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_foreach_multimap_iterators(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc          = DefaultAllocatorInit();
        IntIntMap        map            = MapInit(i32_hash, i32_compare, &alloc);
    // must NOT write back into the map.
    static bool test_map_foreach_pair_by_value(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc     = DefaultAllocatorInit();
        IntIntMap        map       = MapInit(i32_hash, i32_compare, &alloc);
    // address. Writing through it must persist into the map.
    static bool test_map_foreach_value_ptr(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // Each counter must stay 0.
    static bool test_map_foreach_empty_skips_body(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
        };
    
        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/Allocator/Default.h>
    #include <Misra/Std/Container/Map.h>
    #include <Misra/Std/Log.h>
    #include "../../Util/TestRunner.h"
    // ---------------------------------------------------------------------------
    static bool test_find_next_index_honours_full_probe_budget(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = {
    // ---------------------------------------------------------------------------
    static bool test_value_ptr_from_cursor_rejects_index_equal_capacity(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        MapPolicy        policy = {
    
    static bool test_map_contains_and_find(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    
    static bool test_map_get_ptr(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    // value, and the first stored value is the duplicate inserted first.
    static bool test_map_get_first_ptr_is_live(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    // branch in Map.c. Guards `if (!map->capacity) return ...;` lines.
    static bool test_map_empty_queries(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(i32_hash, i32_compare, i32_compare, &alloc);
    
    static bool test_map_get_or_default(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_value_cursor_query(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc     = DefaultAllocatorInit();
        IntIntMap        map       = MapInit(i32_hash, i32_compare, &alloc);
    
    static bool test_map_cursor_invalidated_after_removal(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc  = DefaultAllocatorInit();
        IntIntMap        map    = MapInit(i32_hash, i32_compare, &alloc);
    // neighbour's value and turns this RED.
    static bool test_map_collision_chain_lookup(void) {
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompare(const_hash, i32_compare, i32_compare, &alloc);
            KEY_COUNT = 24
        };
        typedef Map(int, int) IntIntMap;
        DefaultAllocator alloc = DefaultAllocatorInit();
        IntIntMap        map   = MapInitWithValueCompareAndPolicy(const_hash, i32_compare, i32_compare, policy, &alloc);
        };
    
        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");
    }
Last updated on