Newer
Older
libkc / modules / include / kc_overload.h
/**
 * @file kc_overload.h
 * @brief オーバーロード用マクロ。
 * @copyright  2022 - 2023  Nomura Kei
 * @depends none
 */
#ifndef KC_OVERLOAD_H
#define KC_OVERLOAD_H

/**
 * 関数のオーバーロードを実現します。
 * 引数の数に応じて、「指定された関数名(のプレフィックス) + 引数の数」の関数が実行されます。
 *
 * @code
 * 例) add
 * #define add(...) KC_OVERLOAD(add_, __VA_ARGS__)
 *
 * 引数が2つの場合、add_2 の関数が呼び出されます。
 * 引数が3つの場合、add_3 の関数が呼び出されます。
 *    :
 * 引数が9つの場合、add_9 の関数が呼び出されます。
 *
 *
 * @endcode
 *
 * @param func オーバーロードする関数のベース名
 * @param ...  __VA_ARGS__
 * @return 引数に応じて呼び出す関数
 */
#define KC_OVERLOAD(func, ...) KC_OVERLOAD_SUB(func, KC_ARGS_LENGTH(__VA_ARGS__))(__VA_ARGS__)

////////////////////////////////////////////////////////////////////////////////
//
// 以下、オーバーロード実現のためのマクロ群
//

/**
 * 関数名を生成します。
 * 関数名ベース+引数の数の関数名を生成します。
 *
 * 例)
 * 関数名ベース add_
 * 引数の数     1
 *
 * add_1
 *
 * @param func        関数名のベース
 * @param args_length 引数の数
 * @return 引数名
 */
#define KC_OVERLOAD_SUB(func, args_length) KC_STRCAT(func, args_length)

/**
 * 可変長引数の個数を返します。
 *
 * @param ... 可変長引数
 * @return 引数の数
 */
#define KC_ARGS_LENGTH(...) KC_ARGS_LENGTH_SUB(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define KC_ARGS_LENGTH_SUB(v1, v2, v3, v4, v5, v6, v7, v8, v9, LENGTH, ...) LENGTH

/**
 * 指定された文字列を連結します。
 *
 * @param s1 文字列1
 * @param s2 文字列2
 * @return 連結した文字列
 */
#define KC_STRCAT(s1, s2) s1##s2

#endif // KC_OVERLOAD_H