Newer
Older
libj / include / j / overload.hpp
/**
 * @file overload.hpp
 * @brief J Library Overload ヘッダファイル。
 * @copyright  2001 - 2024  Nomura Kei
 * @depends
 */
#ifndef J_OVERLOAD_HPP
#define J_OVERLOAD_HPP

/**
 * 関数のオーバーロードを実現します。
 * テンプレートの特殊化等の際に利用可能です。
 * 引数の数に応じて、「指定された関数名(のプレフィックス) + 引数の数」の関数が実行されます。
 *
 * @code
 * 例) add
 * #define add(...) J_OVERLOAD(add_, __VA_ARGS__)
 *
 * 引数が2つの場合、add_2 の関数が呼び出されます。
 * 引数が3つの場合、add_3 の関数が呼び出されます。
 *    :
 * 引数が9つの場合、add_9 の関数が呼び出されます。
 *
 *
 * @endcode
 *
 * @param func オーバーロードする関数のベース名
 * @param ...  __VA_ARGS__
 * @return 引数に応じて呼び出す関数
 */
#define J_OVERLOAD(func, ...) J_OVERLOAD_SUB(func, J_ARGS_LENGTH(__VA_ARGS__))(__VA_ARGS__)

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

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

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

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

#endif // J_OVERLOAD_HPP