Skip to content
MISRA_OVERLOAD

MISRA_OVERLOAD

Description

Variadic macro overload by argument count. Dispatches a call MISRA_OVERLOAD(Name, ...) to Name_<N>(...) where N is the argument count returned by MISRA_NARG. The caller is responsible for defining each overload (Name_0, Name_1, …) that they want to accept.

Usage:

#define MyInit(…) MISRA_OVERLOAD(MyInit, VA_ARGS) #define MyInit_0() MyInit_1(MisraScope) #define MyInit_1(p) { …, .allocator = ALLOCATOR_OF(p) }

Two indirections so MISRA_NARG fully expands before the ## concatenation in MISRA_OVERLOAD__.

Usage example (Cross-references)

Usage examples (Cross-references)
    /// TAGS: Read, File, I/O, Utility, Allocator
    ///
    #define ReadCompleteFile(...) MISRA_OVERLOAD(ReadCompleteFile, __VA_ARGS__)
    #define ReadCompleteFile_4(filename, data, file_size, capacity)                                                        \
        read_complete_file((filename), (data), (file_size), (capacity), MisraScope)
         .__magic           = MISRA_MAP_MAGIC}
    
    #define MapInitFull(...) MISRA_OVERLOAD(MapInitFull, __VA_ARGS__)
    #define MapInitFull_8(hash_fn, compare_fn, vcmp, kci, kcd, vci, vcd, policy_value)                                     \
        MapInitFull_9(hash_fn, compare_fn, vcmp, kci, kcd, vci, vcd, policy_value, MisraScope)
    /// optional inside a `Scope` block.
    ///
    #define MapInit(...)                   MISRA_OVERLOAD(MapInit, __VA_ARGS__)
    #define MapInit_2(hash_fn, compare_fn) MapInit_3(hash_fn, compare_fn, MisraScope)
    #define MapInit_3(hash_fn, compare_fn, typed_alloc_ptr)                                                                \
    /// Initialize a map with key/value comparators.
    ///
    #define MapInitWithValueCompare(...) MISRA_OVERLOAD(MapInitWithValueCompare, __VA_ARGS__)
    #define MapInitWithValueCompare_3(hash_fn, compare_fn, value_compare_fn)                                               \
        MapInitWithValueCompare_4(hash_fn, compare_fn, value_compare_fn, MisraScope)
    /// Initialize a map with key callbacks and an explicit probing policy.
    ///
    #define MapInitWithPolicy(...) MISRA_OVERLOAD(MapInitWithPolicy, __VA_ARGS__)
    #define MapInitWithPolicy_3(hash_fn, compare_fn, policy_value)                                                         \
        MapInitWithPolicy_4(hash_fn, compare_fn, policy_value, MisraScope)
    /// Initialize a map with key/value comparators and an explicit probing policy.
    ///
    #define MapInitWithValueCompareAndPolicy(...) MISRA_OVERLOAD(MapInitWithValueCompareAndPolicy, __VA_ARGS__)
    #define MapInitWithValueCompareAndPolicy_4(hash_fn, compare_fn, value_compare_fn, policy_value)                        \
        MapInitWithValueCompareAndPolicy_5(hash_fn, compare_fn, value_compare_fn, policy_value, MisraScope)
    /// Initialize a map with deep-copy callbacks for keys and values.
    ///
    #define MapInitWithDeepCopy(...) MISRA_OVERLOAD(MapInitWithDeepCopy, __VA_ARGS__)
    #define MapInitWithDeepCopy_6(hash_fn, compare_fn, key_ci, key_cd, value_ci, value_cd)                                 \
        MapInitWithDeepCopy_7(hash_fn, compare_fn, key_ci, key_cd, value_ci, value_cd, MisraScope)
        )
    
    #define MapInitT(m, ...) MISRA_OVERLOAD(MapInitT, m, __VA_ARGS__)
    #ifdef __cplusplus
    #    define MapInitT_3(m, hash_fn, compare_fn) (TYPE_OF(m) MapInit_3((hash_fn), (compare_fn), MisraScope))
    #endif
    
    #define MapInitWithDeepCopyT(m, ...) MISRA_OVERLOAD(MapInitWithDeepCopyT, m, __VA_ARGS__)
    #ifdef __cplusplus
    #    define MapInitWithDeepCopyT_7(m, hash_fn, compare_fn, key_ci, key_cd, value_ci, value_cd)                         \
    /// TAGS: Init, Vec, Length, Size
    ///
    #define VecInit(...) MISRA_OVERLOAD(VecInit, __VA_ARGS__)
    #define VecInit_0()  VecInit_1(MisraScope)
    #define VecInit_1(allocator_ptr)                                                                                       \
    /// `Scope` block.
    ///
    #define VecInitT(v, ...) MISRA_OVERLOAD(VecInitT, v, __VA_ARGS__)
    #ifdef __cplusplus
    #    define VecInitT_1(v)            (TYPE_OF(v) VecInit_1(MisraScope))
    /// you may omit it and `MisraScope` is used automatically.
    ///
    #define VecInitWithDeepCopy(...)      MISRA_OVERLOAD(VecInitWithDeepCopy, __VA_ARGS__)
    #define VecInitWithDeepCopy_2(ci, cd) VecInitWithDeepCopy_3(ci, cd, MisraScope)
    #define VecInitWithDeepCopy_3(ci, cd, allocator_ptr)                                                                   \
         .__magic     = MISRA_VEC_MAGIC}
    
    #define VecInitWithDeepCopyT(v, ...) MISRA_OVERLOAD(VecInitWithDeepCopyT, v, __VA_ARGS__)
    #ifdef __cplusplus
    #    define VecInitWithDeepCopyT_3(v, ci, cd)            (TYPE_OF(v) VecInitWithDeepCopy_3(ci, cd, MisraScope))
        str_try_init_from_cstr((out), (cstr), (len), ALLOCATOR_OF(allocator_ptr))
    
    #define StrInitFromCstr(...)                MISRA_OVERLOAD(StrInitFromCstr, __VA_ARGS__)
    #define StrInitFromCstr_2(cstr, len)        str_init_from_cstr((cstr), (len), MisraScope)
    #define StrInitFromCstr_3(cstr, len, alloc) str_init_from_cstr((cstr), (len), ALLOCATOR_OF(alloc))
    #define StrInitFromCstr_3(cstr, len, alloc) str_init_from_cstr((cstr), (len), ALLOCATOR_OF(alloc))
    
    #define StrInitFromZstr(...)       MISRA_OVERLOAD(StrInitFromZstr, __VA_ARGS__)
    #define StrInitFromZstr_1(zstr)    StrInitFromCstr_2((zstr), ZstrLen(zstr))
    #define StrInitFromZstr_2(zstr, a) StrInitFromCstr_3((zstr), ZstrLen(zstr), (a))
    #define StrInitFromZstr_2(zstr, a) StrInitFromCstr_3((zstr), ZstrLen(zstr), (a))
    
    #define StrZ(...)       MISRA_OVERLOAD(StrZ, __VA_ARGS__)
    #define StrZ_1(zstr)    StrInitFromZstr_1((zstr))
    #define StrZ_2(zstr, a) StrInitFromZstr_2((zstr), (a))
    #define StrZ_2(zstr, a) StrInitFromZstr_2((zstr), (a))
    
    #define StrInitFromStr(...)      MISRA_OVERLOAD(StrInitFromStr, __VA_ARGS__)
    #define StrInitFromStr_1(str)    StrInitFromCstr_2((str)->data, (str)->length)
    #define StrInitFromStr_2(str, a) StrInitFromCstr_3((str)->data, (str)->length, (a))
    #define StrInitFromStr_2(str, a) StrInitFromCstr_3((str)->data, (str)->length, (a))
    
    #define StrDup(...)      MISRA_OVERLOAD(StrDup, __VA_ARGS__)
    #define StrDup_1(str)    StrInitFromStr_1((str))
    #define StrDup_2(str, a) StrInitFromStr_2((str), (a))
    /// pass a typed allocator handle or a raw `Allocator *`.
    ///
    #define StrInit(...) MISRA_OVERLOAD(StrInit, __VA_ARGS__)
    #ifdef __cplusplus
    #    define StrInit_0()          (Str VecInit_1(MisraScope))
    /// allocator handle or a raw `Allocator *`.
    ///
    #define ListInit(...)               MISRA_OVERLOAD(ListInit, __VA_ARGS__)
    #define ListInit_0()                ListInitWithDeepCopy_3(NULL, NULL, MisraScope)
    #define ListInit_1(typed_alloc_ptr) ListInitWithDeepCopy_3(NULL, NULL, typed_alloc_ptr)
    /// Typed-cast variant of `ListInit`.
    ///
    #define ListInitT(l, ...)               MISRA_OVERLOAD(ListInitT, l, __VA_ARGS__)
    #define ListInitT_1(l)                  ListInitWithDeepCopyT_4(l, NULL, NULL, MisraScope)
    #define ListInitT_2(l, typed_alloc_ptr) ListInitWithDeepCopyT_4(l, NULL, NULL, typed_alloc_ptr)
    /// allocator argument is optional inside a `Scope` block.
    ///
    #define ListInitWithDeepCopy(...)      MISRA_OVERLOAD(ListInitWithDeepCopy, __VA_ARGS__)
    #define ListInitWithDeepCopy_2(ci, cd) ListInitWithDeepCopy_3(ci, cd, MisraScope)
    #define ListInitWithDeepCopy_3(ci, cd, typed_alloc_ptr)                                                                \
         .__magic     = MISRA_LIST_MAGIC}
    
    #define ListInitWithDeepCopyT(l, ...) MISRA_OVERLOAD(ListInitWithDeepCopyT, l, __VA_ARGS__)
    #ifdef __cplusplus
    #    define ListInitWithDeepCopyT_3(l, ci, cd) (TYPE_OF(l) ListInitWithDeepCopy_3(ci, cd, MisraScope))
    /// TAGS: BitVec, Convert, String
    ///
    #define BitVecTryToStr(...)              MISRA_OVERLOAD(BitVecTryToStr, __VA_ARGS__)
    #define BitVecTryToStr_2(out, bv)        bitvec_try_to_str((out), (bv), BitVecGetAllocator((bv)))
    #define BitVecTryToStr_3(out, bv, alloc) bitvec_try_to_str((out), (bv), (alloc))
    /// TAGS: BitVec, Convert, String
    ///
    #define BitVecToStr(...)         MISRA_OVERLOAD(BitVecToStr, __VA_ARGS__)
    #define BitVecToStr_1(bv)        bitvec_to_str((bv), BitVecGetAllocator((bv)))
    #define BitVecToStr_2(bv, alloc) bitvec_to_str((bv), (alloc))
    /// `Allocator *`.
    ///
    #define BitVecInit(...) MISRA_OVERLOAD(BitVecInit, __VA_ARGS__)
    #define BitVecInit_0()  BitVecInit_1(MisraScope)
    #ifdef __cplusplus
    #include "Type.h"
    
    #define GraphInit(...)               MISRA_OVERLOAD(GraphInit, __VA_ARGS__)
    #define GraphInit_0()                GraphInitWithDeepCopy_3(NULL, NULL, MisraScope)
    #define GraphInit_1(typed_alloc_ptr) GraphInitWithDeepCopy_3(NULL, NULL, typed_alloc_ptr)
    #define GraphInit_1(typed_alloc_ptr) GraphInitWithDeepCopy_3(NULL, NULL, typed_alloc_ptr)
    
    #define GraphInitT(g, ...)               MISRA_OVERLOAD(GraphInitT, g, __VA_ARGS__)
    #define GraphInitT_1(g)                  GraphInitWithDeepCopyT_4((g), NULL, NULL, MisraScope)
    #define GraphInitT_2(g, typed_alloc_ptr) GraphInitWithDeepCopyT_4((g), NULL, NULL, typed_alloc_ptr)
    #define GraphInitT_2(g, typed_alloc_ptr) GraphInitWithDeepCopyT_4((g), NULL, NULL, typed_alloc_ptr)
    
    #define GraphInitWithDeepCopy(...)                       MISRA_OVERLOAD(GraphInitWithDeepCopy, __VA_ARGS__)
    #define GraphInitWithDeepCopy_2(ci, cd)                  GRAPH_INIT_WITH_DEEP_COPY_VALUE((ci), (cd), MisraScope)
    #define GraphInitWithDeepCopy_3(ci, cd, typed_alloc_ptr) GRAPH_INIT_WITH_DEEP_COPY_VALUE((ci), (cd), typed_alloc_ptr)
    #define GraphInitWithDeepCopy_3(ci, cd, typed_alloc_ptr) GRAPH_INIT_WITH_DEEP_COPY_VALUE((ci), (cd), typed_alloc_ptr)
    
    #define GraphInitWithDeepCopyT(g, ...) MISRA_OVERLOAD(GraphInitWithDeepCopyT, g, __VA_ARGS__)
    #ifdef __cplusplus
    #    define GraphInitWithDeepCopyT_3(g, ci, cd) (TYPE_OF(g) GRAPH_INIT_WITH_DEEP_COPY_VALUE((ci), (cd), MisraScope))
    /// - `IntTryToStr(out, value, alloc)` - uses the explicit allocator.
    ///
    #define IntTryToStr(...)                 MISRA_OVERLOAD(IntTryToStr, __VA_ARGS__)
    #define IntTryToStr_2(out, value)        int_try_to_str((out), (value), (value)->bits.allocator)
    #define IntTryToStr_3(out, value, alloc) int_try_to_str((out), (value), (alloc))
    /// - `IntToStr(value, alloc)` - uses the explicit allocator.
    ///
    #define IntToStr(...)            MISRA_OVERLOAD(IntToStr, __VA_ARGS__)
    #define IntToStr_1(value)        int_to_str((value), (value)->bits.allocator)
    #define IntToStr_2(value, alloc) int_to_str((value), (alloc))
    ///       uses the explicit allocator.
    ///
    #define IntTryToStrRadix(...) MISRA_OVERLOAD(IntTryToStrRadix, __VA_ARGS__)
    #define IntTryToStrRadix_4(out, value, radix, uppercase)                                                               \
        int_try_to_str_radix((out), (value), (radix), (uppercase), (value)->bits.allocator)
    /// - `IntToStrRadix(value, radix, uppercase, alloc)` - explicit allocator.
    ///
    #define IntToStrRadix(...) MISRA_OVERLOAD(IntToStrRadix, __VA_ARGS__)
    #define IntToStrRadix_3(value, radix, uppercase)                                                                       \
        int_to_str_radix((value), (radix), (uppercase), (value)->bits.allocator)
    /// TAGS: Int, Init, Zero, Construct
    ///
    #define IntInit(...)             MISRA_OVERLOAD(IntInit, __VA_ARGS__)
    #define IntInit_0()              ((Int) {.bits = BitVecInit_1(MisraScope)})
    #define IntInit_1(allocator_ptr) ((Int) {.bits = BitVecInit_1(allocator_ptr)})
    /// TAGS: Float, Convert, String, Decimal
    ///
    #define FloatTryToStr(...)                 MISRA_OVERLOAD(FloatTryToStr, __VA_ARGS__)
    #define FloatTryToStr_2(out, value)        float_try_to_str((out), (value), (value)->significand.bits.allocator)
    #define FloatTryToStr_3(out, value, alloc) float_try_to_str((out), (value), (alloc))
    /// TAGS: Float, Convert, String, Decimal
    ///
    #define FloatToStr(...)            MISRA_OVERLOAD(FloatToStr, __VA_ARGS__)
    #define FloatToStr_1(value)        float_to_str((value), (value)->significand.bits.allocator)
    #define FloatToStr_2(value, alloc) float_to_str((value), (alloc))
    /// TAGS: Float, Init, Zero, Construct
    ///
    #define FloatInit(...)             MISRA_OVERLOAD(FloatInit, __VA_ARGS__)
    #define FloatInit_0()              ((Float) {.negative = false, .significand = IntInit_1(MisraScope), .exponent = 0})
    #define FloatInit_1(allocator_ptr) ((Float) {.negative = false, .significand = IntInit_1(allocator_ptr), .exponent = 0})
    /// SUCCESS : Returns initialized config object.
    ///
    #define KvConfigInit(...) MISRA_OVERLOAD(KvConfigInit, __VA_ARGS__)
    #define KvConfigInit_0()  KvConfigInit_1(MisraScope)
    #define KvConfigInit_1(allocator_ptr)                                                                                  \
Last updated on